Redo for loop iteration in Python

前端 未结 6 1401
灰色年华
灰色年华 2020-12-10 04:07

Does Python have anything in the fashion of a \"redo\" statement that exists in some languages?

(The \"redo\" statement is a statement that (just like \"break\" or \

相关标签:
6条回答
  • 2020-12-10 04:15

    There is no redo in python. A very understandable solution is as follow:

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

    It's clear enough to do not add comments

    Continue will work as if it was in the for loop

    But break is not useable, this solution make break useable but the code is less clear.

    0 讨论(0)
  • 2020-12-10 04:16

    I just meet the same question when I study perl,and I find this page.

    follow the book of 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;
        }
    }
    

    and how to achieve it on Python ?? follow the code:

    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 has not the "redo" syntax,but we can make a 'while' loop in some function until get what we want when we iter the list.

    0 讨论(0)
  • 2020-12-10 04:19

    No, it doesn't. I would suggest using a while loop and resetting your check variable to the initial value.

    count = 0
    reset = 0
    while count < 9:
       print 'The count is:', count
       if not someResetCondition:
           count = count + 1
    
    0 讨论(0)
  • 2020-12-10 04:26

    This is my solution using iterators:

    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('---')
    
    • Needs explicit continue
    • redone is an extra feature
    • For Python2 use def next(self) instead of def __next__(self)
    • requires iterator to be defined before the loop
    0 讨论(0)
  • 2020-12-10 04:29

    No, Python doesn't have direct support for redo. One option would something faintly terrible involving nested loops like:

    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
    

    but this mean that breaking the outer loop is impossible within the "redo-able" block without resorting to exceptions, flag variables, or packaging the whole thing up as a function.

    Alternatively, you use a straight while loop that replicates what for loops do for you, explicitly creating and advancing the iterator. It has its own issues (continue is effectively redo by default, you have to explicitly advance the iterator for a "real" continue), but they're not terrible (as long as you comment uses of continue to make it clear you intend redo vs. continue, to avoid confusing maintainers). To allow redo and the other loop operations, you'd do something like:

    # 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)
    

    The above could also be done with a try/except StopIteration: instead of two-arg next with a sentinel, but wrapping the whole loop with it risks other sources of StopIteration being caught, and doing it at a limited scope properly for both inner and outer next calls would be extremely ugly (much worse than the sentinel based approach).

    0 讨论(0)
  • 2020-12-10 04:32

    Not very sofiscated but easy to read, using a while and an increment at the end of the loop. So any continue in between will have the effect of a redo. Sample to redo every multiple of 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
    

    Result: 00123345667899

    0 讨论(0)
提交回复
热议问题