18

Python 是否有某些语言中存在的“重做”语句形式的东西?

(“redo”语句是一个(就像“break”或“continue”一样)影响循环行为的语句——它在最内层循环的开始处跳转并再次开始执行。)

4

7 回答 7

9

不,Python 没有直接支持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

但这意味着如果不求助于异常、标记变量或将整个事情打包成一个函数,break就不可能在“-able”块中执行外部循环。redo

或者,您使用直接while循环来复制for循环为您所做的事情,显式地创建和推进迭代器。它有自己的问题(默认情况下continue有效redo,您必须显式推进迭代器以获得“真实” continue),但它们并不可怕(只要您评论使用 ofcontinue以明确您的意图redovs. 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/而不是使用aexcept StopIteration:的双参数来完成,但是用它包裹整个循环可能会导致其他来源被捕获,并且对于内部和外部调用在有限的范围内正确执行它会非常难看(比基于方法差得多)。nextsentinelStopIterationnextsentinel

于 2016-04-12T12:59:41.577 回答
6

不,它没有。我建议使用 while 循环并将您的检查变量重置为初始值。

count = 0
reset = 0
while count < 9:
   print 'The count is:', count
   if not someResetCondition:
       count = count + 1
于 2016-04-12T12:54:27.060 回答
2

我在学习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”循环,直到迭代列表时得到我们想要的。

于 2016-10-25T02:37:47.977 回答
1

不是很复杂但易于阅读,while在循环结束时使用 a 和增量。所以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

于 2018-02-01T23:18:05.157 回答
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是一个额外的功能
  • 对于 Python2 使用def next(self)而不是def __next__(self)
  • 需要iterator在循环之前定义
于 2016-04-12T14:02:20.220 回答
0

python中没有重做。一个非常容易理解的解决方案如下:

for x in mylist:
    redo = True
    while redo:
        redo = False

        If should_redo:
            redo = True

不加评论就够清楚了

Continue将像在 for 循环中一样工作

但是break不可用,这个解决方案可以break使用,但代码不太清楚。

于 2020-08-24T16:17:59.667 回答
0

这是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
于 2021-11-16T22:25:49.540 回答