Python 是否有类似其他语言的 "redo" 语句呢?
("redo" 语句是一种会影响循环行为的语句,就像 "break" 或 "continue" 一样——它跳到最内层循环的开头并重新开始执行。)
Python 是否有类似其他语言的 "redo" 语句呢?
("redo" 语句是一种会影响循环行为的语句,就像 "break" 或 "continue" 一样——它跳到最内层循环的开头并重新开始执行。)
redo
。一个选项是使用嵌套循环,但这种方法可能会有些糟糕,例如: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
但这意味着在“redo
”块内部无法中断外部循环,除非使用异常、标志变量或将整个事情打包为函数。
或者,您可以使用直接的while
循环来复制for
循环为您完成的操作,明确地创建和推进迭代器。它有自己的问题(continue
默认情况下有效地是redo
,您必须显式地推进迭代器以进行“真正”的continue
),但它们并不可怕(只要您注释使用continue
以清楚地表明您打算使用redo
vs. 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)
try
/except StopIteration:
来代替带有sentinel
的两个参数的next
,但是将整个循环包装在其中会冒险捕获其他StopIteration
源,并且在有限的范围内正确处理内部和外部next
调用会非常丑陋(比sentinel
方法更糟糕)。count = 0
reset = 0
while count < 9:
print 'The count is:', count
if not someResetCondition:
count = count + 1
reset
不能复制其他语言中 redo
的功能。redo
是 continue
,但没有循环增量/前进步骤,但它不会从头重新开始循环;您只需使 count
增量可选,而不是有一个 reset
变量。 - ShadowRangerredo
的语言是 Perl,并且它的行为是这样的。注意:如果你要替换 for count in range(10):
,编辑后的代码是可以的,但它并不能很好地适用于任意可迭代对象;我在 我的回答 中的第二个代码示例是完全通用的版本。 - ShadowRanger我在学习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;
}
}
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没有"redo"语法,但是我们可以在某些函数中使用'while'循环,直到我们迭代列表并得到想要的结果。
虽然不是很复杂,但易于阅读。使用 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
这是我使用迭代器的解决方案:
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
这里提供了一个Python 3.8+的解决方案,因为现在我们有了 :=
运算符:
for key in mandatory_attributes: # example with a dictionary
while not (value := input(f"{key} (mandatory): ")):
print("You must enter a value")
mandatory_attributes[key] = value
Python 中没有重做功能。 一个非常易懂的解决方案如下:
for x in mylist:
redo = True
while redo:
redo = False
If should_redo:
redo = True
代码已经足够清晰,不需要添加注释。
Continue
语句将会像在 for 循环中一样工作。
但是 break
语句无法使用,这个 solution 可以让 break
语句可用,但是代码会变得不太清晰。
while
循环,在某次评估后重新设置计数器/条件。 - miradulocontinue
和break
没有区别;如果您接受它们作为不仅仅是“goto”的东西,则redo
并不更糟糕(或更好)。 - ShadowRanger