2013-01-17 164 views
16

所以我希望做這樣的事情:搬回一個迭代的for循環

for i in range(5): 
    print(i); 
    if(condition==true): 
     i=i-1; 

然而,無論出於何種原因,即使我遞減我,循環似乎沒有注意到。有什麼方法可以重複迭代?

+3

當你移動時不要改變汽車的輪子。 –

+1

下面有很多答案可以解釋如何以這種方式增加'i'。我想知道你在用'i'做什麼,因爲可能有更清晰的方法來處理這些代碼。 – Johnsyweb

回答

20

for Python中的循環總是前進。如果你希望能夠向後移動,你必須使用一個不同的機制,如while

i = 0 
while i < 5: 
    print(i) 
    if condition: 
     i=i-1 
    i += 1 

甚至更​​好:

i = 0 
while i < 5: 
    print(i) 
    if condition: 
     do_something() 
     # don't increment here, so we stay on the same value for i 
    else: 
     # only increment in the case where we're not "moving backwards" 
     i += 1 
+2

+1中進行更清晰的重構 – wim

3

您對Python中的循環存在誤解。 for循環並不在意你在每次迭代時如何處理i,因爲它根本與循環的邏輯無關。修改i只是重新綁定一個局部變量。

您將需要使用while循環,實現你期望的行爲,其中的i狀態確實會影響循環的控制流程:

import random 

i = 0 
while i < 5: 
    print(i) 
    i += 1 
    if random.choice([True, False]): 
     i -= 1 
6

Python的循環使用range是由設計不同於C/C++/Java for -loops。對於每次迭代,我都將下一個值設置爲range(5),無論您如何處理i

你可以使用一個while循環,而不是:

i = 0 
while i<5: 
    print i 
    if condition: 
     continue 
    i+=1 

但說實話:我想你原來的問題又退一步想。可能你會找到更好的解決方案,因爲這樣的循環總是容易出錯。 Python for -loops的設計有所不同,這是有原因的。

2

利用while循環:

i = 0 
while i < 5: 
    print(i) 
    if condition: 
     i -= 1 
    i += 1 

正如已經提到的,這是相當unidiomatic Python的。也許如果你發佈你想要達到的目標,我們可以給出一些更好的建議。

+0

如果條件總是正確的,那麼'i'會發生什麼? – Gabe

+1

您正處於無限循環 –

2

range(5)在它通4創建了數字0列表 - [0, 1, 2, 3, 4]

當您在其上運行for循環時,您正在迭代列表。做i-= 1將只會減少列表中該特定元素的,並且迭代將繼續。

像這裏提供的其他答案一樣,你應該使用一個while循環。

i= 0 
while i<5: 
    # do stuff 
    if #condition: 
     i-= 1 # or + 
    i+= 1 
2

重複很多其他的答案,只是爲了完整性,您將需要使用while loop

i = 0 
while i < 5: 
    print(i) 
    if (not condition): 
     i+=1 

如果你想回遷循環迭代(而不是重複迭代),然後使用此:

i = 0 
while i < 5: 
    print(i) 
    if (condition): 
     i -= 1 
    else: 
     i += 1 

從本質上講,while i < 5評估在每次迭代中,如果i < 5檢查。因此,通過減小/不改變i,我們得到的是這樣的:(的i值)

在不改變:1->2->3-(condition satisfied)> 3 -> 4 -> 5

遞減:1->2->3-(condition satisfied)>2 -> 3 -> 4 -> 5

之所以i=i-1在for循環不作它重複迭代很簡單。在for循環中,i被分配for循環中下一項的值。只要Python能夠將下一個項目分配給它,Python可以不在乎你如何處理i。因此,for循環for i in <your_iterable>:<do whatever>是接近這個:

_i = 0 
_length = len(<your_iterable>) 
while _i < _length: 
    i = _i 
    _i += 1 
    <do whatever> 

然而,在這個比喻中,您將無法訪問_預測變量(_i_length)。這就是我簡化for loop的邏輯的方法。請注意,無論分配給什麼i,它都將在下一次迭代時分配給_i,並且該循環實際上並不關心i是什麼。

1

在Python中,可以在迭代器(infor..in循環中)與其消費者(循環內的代碼)之間建立雙向交換。爲了達到這個目的,你可以在用戶代碼中使用send在生成器中「注入」一個值。在你的情況下,只要符合條件就可以簡單地發回當前值,並將range調用包裝在發生器中,該發生器重複發送給它的任何東西。這裏有一些代碼供你玩,故意爲了清晰而詳細說明:

def repeateble(it): 
    buf, it = None, iter(it) 
    while True: 
     if buf is None: 
      # the buffer is empty, send them the next elem 
      val = next(it) 
     else: 
      # there's something in the buffer 
      # let's send that back 
      val = buf 

     # send the value and wait what they say 
     back = yield val 

     if back: 
      # they've sent us something! 
      # give them some dummy value as a result of send() 
      yield None 
      # and save what they've sent in a buffer 
      # for the next iteration 
      buf = back 

     else: 
      # they haven't sent anything 
      # empty the buffer 
      buf = None 


from random import randint 

# create a repeateble generator 
rng = repeateble(range(100)) 

for x in rng: 
    print(x) 

    # check "some condition"... 
    if randint(1, 100) > 80: 
     print('repeat:') 
     # send the current value back to the generator 
     # it will be returned on the next iteration 
     rng.send(x)