web-dev-qa-db-ja.com

python:ループの再開

私が持っています:

for i in range(2,n):
    if(something):
       do something
    else:
       do something else
       i = 2 **restart the loop

しかし、それはうまくいかないようです。そのループを再開する方法はありますか?

ありがとう

21
cbrulak

それは最も明白な答えであるため、そのロジックが適用可能な別のタイプのループの使用を検討することをお勧めします。

おそらくa:

i=2
while i < n:
    if something:
       do something
       i += 1
    else: 
       do something else  
       i = 2 #restart the loop  
33
gnomed

ループ内からインデックス変数iを変更しても、期待どおりに動作しない可能性があります。代わりにwhileループを使用して、ループ変数の増分を自分で制御する必要がある場合があります。 forループを回るたびに、irange()からの次の値で再割り当てされます。したがって、次のようなもの:

i = 2
while i < n:
    if(something):
        do something
    else:
        do something else
        i = 2 # restart the loop
        continue
    i += 1

私の例では、 continue ステートメントはループの先頭に戻り、その反復のi += 1ステートメントをスキップします。それ以外の場合、iは期待どおりに増分されます(forループと同じ)。

13
Greg Hewgill

ジェネレータの send() method を使用した例を次に示します。

def restartable(seq):
    while True:
        for item in seq:
            restart = yield item
            if restart:
                break
        else:
            raise StopIteration

使用例:

x = [1, 2, 3, 4, 5]
total = 0
r = restartable(x)
for item in r:
    if item == 5 and total < 100:
        total += r.send(True) 
    else:
        total += item
3
Joel Cornett

より一般的に使用できる代替案を投稿したかっただけです。既存のソリューションのほとんどは、これを回避するためにループインデックスを使用しています。ただし、インデックスを使用する必要はありません。ここで重要なのは、ループ変数が非表示になっているforループとは異なり、ループ変数が公開されることです。

イテレーター/ジェネレーターで非常によく似たことができます。

x = [1,2,3,4,5,6]
xi = iter(x)
ival = xi.next()
while not exit_condition(ival):
    # Do some ival stuff
    if ival == 4:
        xi = iter(x)
    ival = xi.next()

それほどクリーンではありませんが、ループイテレータ自体に書き込む機能は保持しています。

通常、これを実行したい場合は、アルゴリズムが間違っているため、より簡潔に書き直す必要があります。おそらくあなたが本当にやりたいことは、代わりにジェネレータ/コルーチンを使うことでしょう。しかし、それは少なくとも可能です。

1
Corley Brigman
a = ['1', '2', '3']
ls = []
count = False

while ls != a :
    print(a[count])
    if a[count] != a[-1] :
        count = count + 1
    else :
        count = False

Whileループを再開します。

0
BrunoC7