2013-01-17 12 views
16

のために反復をバック移動:だから私はこのような何かをしたいループ

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

しかし、何らかの理由で、私は私をデクリメントてるにもかかわらず、ループが気づいていないようです。反復を繰り返す方法はありますか?

+3

あなたが移動するときに車の車輪を変更しないでください。 –

+1

このように 'i'をインクリメントする方法を正確に説明する以下の答えがたくさんあります。このコードを処理する方法がはるかに分かりやすいので、あなたが 'i'でやっていることを理解したいと思います。 – Johnsyweb

答えて

20

for Pythonのループは常に進んでいます。

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を変更するだけでローカル変数がリバインドされます。あなたがiの状態がループの制御フローに影響を与えない場合は、あなたが期待している動作を実現するために、whileループを使用する必要があります

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とは異なります。反復ごとに、iはrange(5)の次の値に設定されます。その間にはiを実行します。

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

しかし、正直なところ:

あなたが代わりにwhileループを使用することができ、私はあなたの元の問題について再びステップと思うだろう。おそらく、そのようなループは常にエラーを起こしやすいので、より良い解決策を見つけるでしょう。 Python for -loopsが異なるように設計されている理由があります。

2

whileループ活用:述べたよう

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

が、これはむしろunidiomaticパイソンあります。おそらく、達成しようとしていることを投稿した場合は、より良い助言を与えることができます。

+0

条件が常に真である場合、 'i'はどうなりますか? – Gabe

+1

あなたは無限ループに入っています –

2

range(5)がそれに4スルー数字0のリストを作成します。

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

あるいはさらに良い:あなたが後方に移動することができるようにしたい場合は、そのようwhileとして、別のメカニズムを使用する必要があります。 - [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 < 5場合は基本的に

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

を、while i < 5は各反復時に評価し、チェックします。 (iの値)

が変化していない:1->2->3-(condition satisfied)> 3 -> 4 -> 5

デクリメント:1->2->3-(condition satisfied)>2 -> 3 -> 4 -> 5

する理由はなぜi=i-1でのループのためになりません。したがってiを変更しない/デクリメントすることによって、我々はこのような何かを得ます反復を繰り返すのは簡単です。 forループでは、iにforループの次の項目の値が割り当てられます。 Pythonはiで次の項目を割り当てることができる限り、自分が何をしているかを気にする必要はありません。このように、ループ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では、イテレータ(for..inループ内の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) 
関連する問題