2013-03-31 39 views
4

我在遍歷一個列表。迭代期間可以將一個元素添加到此列表中。所以問題是循環只能遍歷這個列表的原始長度。你如何創建一個動態範圍的循環?

我的代碼:

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 

我一直在使用for i in range(1, len(srcPts)):嘗試,但再次的範圍內保持不變,即使經過項目已被添加到列表中。

回答

4

問題是len(srcPts)只會計算一次,當您將其作爲參數傳遞給range生成器時。所以你需要有一個終止條件,在每次迭代過程中重複計算當前的長度srcPts。有很多方法可以做到這一點,如:

while i < len(srcPts): 


    .... 
+0

謝謝,我這樣一個Python菜鳥。 –

8

您需要使用while循環相反在這種情況下:

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

一個for循環爲您的列表創建一個迭代器,一次。一旦創建迭代器不知道你改變了循環中的列表。此處顯示的while變體代替每次重新計算的長度。

+0

好吧,那不是真的。 Python允許你改變你正在迭代的列表。實際上,當你追加到列表中時,它將掃描這個添加的元素;插入元素也是一樣。爲了迭代你的列表副本,你可以寫'for i in lst [:]:'或者做其他的技巧。更多關於[這裏](http://docs.python.org/2/tutorial/controlflow.html#for-statements)。 –

+0

@SergeyIvanov:我沒有說Python不允許你,我說'for'循環不知道列表被改變了。請注意,OP *已在此處使用切片*。他正在循環部分副本(除第一個元素外)。 –

+0

@SergeyIvanov:這裏就是要點; OP *希望循環包含插入到循環體中的添加元素*。 –

1

在行:

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

切片使得scrPtrs的一個新的副本,所以它是固定的大小。

免責聲明:感覺不對修改的列表是迭代結束了,但是這個工程......

創建一個迭代器在列表上防止拷貝,仍然允許添加項目和插入:

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) 

輸出:

2 
7 
2 
7 
3 
4 
5 
2 
7 
2 
7 
6