10

I am iterating through a list. An element could be added to this list during an iteration. So the problem is that the loop only iterates through the original length of this list.

My code:

    i = 1
    for p in srcPts[1:]:  # skip the first item.
        pt1 = srcPts[i - 1]["Point"]
        pt2 = p["Point"]

        d = MathUtils.distance(pt1, pt2)
        if (D + d) >= I:
            qx = pt1.X + ((I - D) / d) * (pt2.X - pt1.X)
            qy = pt1.Y + ((I - D) / d) * (pt2.Y - pt1.Y)
            q  = Point(float(qx), float(qy))
            # Append new point q.
            dstPts.append(q)
            # Insert 'q' at position i in points s.t. 'q' will be the next i.
            srcPts.insert(i, {"Point": q})
            D = 0.0
        else:
            D += d
        i += 1

I've tried using for i in range(1, len(srcPts)): but again the range stays the same even after more items have been added to the list.

4

3 回答 3

10

You need to use a while loop instead in this case:

i = 1
while i < len(srcPts):
    # ...
    i += 1

A for loop creates an iterator for your list, once. And once created that iterator does not know that you altered the list in the loop. The while variant shown here recalculates the length each time instead.

于 2013-03-31T01:45:02.190 回答
7

The problem is that len(srcPts) is only computed once, when you pass it as an argument to the range generator. So you need to have a terminating condition that repeatedly evaluates the current length of srcPts during each iteration. There's many ways to do this, such as :

while i < len(srcPts):


  ....
于 2013-03-31T01:42:10.367 回答
2

In the line:

for p in srcPts[1:]:  # skip the first item.

slicing makes a new copy of scrPtrs, so it is fixed size.

Disclaimer: It feels wrong to modify a list being iterator over, yet this works...

Create an iterator over the list prevents the copy and still allows items to be added and inserted:

L = [1,2,2,3,4,5,2,2,6]
it = iter(L)
next(it) # skip the first item
for i,p in enumerate(it,1):
    if p == 2:
        L.insert(i+1,7) # insert a 7 as the next item after each 2
    print(p)

Output:

2
7
2
7
3
4
5
2
7
2
7
6
于 2013-03-31T01:53:55.497 回答