Pythonには、一部の言語に存在する「やり直し」ステートメントのようなものがありますか?
(「redo」ステートメントは、(「break」または「continue」のように)ループ動作に影響を与えるステートメントです。最も内側のループの先頭でジャンプし、実行を再開します。)
いいえ、そうではありません。 whileループを使用して、チェック変数を初期値にリセットすることをお勧めします。
count = 0
reset = 0
while count < 9:
print 'The count is:', count
if not someResetCondition:
count = count + 1
いいえ、Pythonはredo
を直接サポートしていません。1つのオプションは、次のようなネストされたループを含むかすかにひどいものです。
for x in mylist:
while True:
...
if shouldredo:
continue # continue becomes equivalent to redo
...
if shouldcontinue:
break # break now equivalent to continue on outer "real" loop
...
break # Terminate inner loop any time we don't redo
ただし、これは、「break
-able」ブロック内で、例外に頼ったり、変数にフラグを立てたり、すべてを関数としてパッケージ化したりしない限り、外側のループをredo
することは不可能であることを意味します。
または、while
ループが行うことを複製するストレートfor
ループを使用して、イテレータを明示的に作成して進めます。それには独自の問題があります(デフォルトではcontinue
は事実上redo
であり、「実際の」continue
のイテレータを明示的に進める必要があります)が、ひどいわけではありません( continue
の使用をコメントして、メンテナの混乱を避けるためにredo
とcontinue
の意図を明確にする限り)。 redo
およびその他のループ操作を許可するには、次のようにします。
# Create guaranteed unique sentinel (can't use None since iterator might produce None)
sentinel = object()
iterobj = iter(mylist) # Explicitly get iterator from iterable (for does this implicitly)
x = next(iterobj, sentinel) # Get next object or sentinel
while x is not sentinel: # Keep going until we exhaust iterator
...
if shouldredo:
continue
...
if shouldcontinue:
x = next(iterobj, sentinel) # Explicitly advance loop for continue case
continue
...
if shouldbreak:
break
...
# Advance loop
x = next(iterobj, sentinel)
上記は、2つの引数のtry
とnext
の代わりにsentinel
/except StopIteration:
を使用して実行することもできますが、ループ全体をラップすると他のソースが危険にさらされますStopIteration
がキャッチされ、内部と外部の両方のnext
呼び出しに対して限定されたスコープで適切に実行すると、非常に醜くなります(sentinel
ベースのアプローチよりもはるかに悪い)。
Perlを勉強しているときに同じ質問に出くわし、このページを見つけました。
perlの本に従ってください:
my @words = qw(fred barney pebbles dino wilma betty);
my $error = 0;
my @words = qw(fred barney pebbles dino wilma betty);
my $error = 0;
foreach (@words){
print "Type the Word '$_':";
chomp(my $try = <STDIN>);
if ($try ne $_){
print "Sorry - That's not right.\n\n";
$error++;
redo;
}
}
そしてそれをPython ??で達成する方法はコードに従ってください:
tape_list=['a','b','c','d','e']
def check_tape(Origin_tape):
errors=0
while True:
tape=raw_input("input %s:"%Origin_tape)
if tape == Origin_tape:
return errors
else:
print "your tape %s,you should tape %s"%(tape,Origin_tape)
errors += 1
pass
all_error=0
for char in tape_list:
all_error += check_tape(char)
print "you input wrong time is:%s"%all_error
Pythonには「やり直し」構文はありませんが、リストを反復処理するときに必要なものが得られるまで、一部の関数で「while」ループを作成できます。
これは、イテレータを使用した私のソリューションです。
_class redo_iter(object):
def __init__(self, iterable):
self.__iterator = iter(iterable)
self.__started = False
self.__redo = False
self.__last = None
self.__redone = 0
def __iter__(self):
return self
def redo(self):
self.__redo = True
@property
def redone(self):
return self.__redone
def __next__(self):
if not (self.__started and self.__redo):
self.__started = True
self.__redone = 0
self.__last = next(self.__iterator)
else:
self.__redone += 1
self.__redo = False
return self.__last
# Display numbers 0-9.
# Display 0,3,6,9 doubled.
# After a series of equal numbers print --
iterator = redo_iter(range(10))
for i in iterator:
print(i)
if not iterator.redone and i % 3 == 0:
iterator.redo()
continue
print('---')
_
continue
が必要redone
は追加機能ですdef next(self)
の代わりにdef __next__(self)
を使用しますiterator
を定義する必要がありますあまり洗練されていませんが、ループの最後にwhile
とインクリメントを使用して、読みやすくなっています。したがって、間にあるcontinue
は、やり直しの効果があります。 3の倍数ごとにやり直すサンプル。
redo = True # To ends redo condition in this sample only
i = 0
while i<10:
print(i, end='')
if redo and i % 3 == 0:
redo = False # To not loop indifinively in this sample
continue # Redo
redo = True
i += 1
結果:00123345667899