Why does python use 'else' after for and while loops?

前端 未结 21 1906
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-11-21 06:57

I understand how this construct works:

for i in range(10):
    print(i)

    if i == 9:
        print(\"Too big - I\'m         


        
相关标签:
21条回答
  • 2020-11-21 07:31

    You could think of it like, else as in the rest of the stuff, or the other stuff, that wasn't done in the loop.

    0 讨论(0)
  • 2020-11-21 07:32

    Great answers are:

    • this which explain the history, and
    • this gives the right citation to ease yours translation/understanding.

    My note here comes from what Donald Knuth once said (sorry can't find reference) that there is a construct where while-else is indistinguishable from if-else, namely (in Python):

    x = 2
    while x > 3:
        print("foo")
        break
    else:
        print("boo")
    

    has the same flow (excluding low level differences) as:

    x = 2
    if x > 3:
        print("foo")
    else:
        print("boo")
    

    The point is that if-else can be considered as syntactic sugar for while-else which has implicit break at the end of its if block. The opposite implication, that while loop is extension to if, is more common (it's just repeated/looped conditional check), because if is often taught before while. However that isn't true because that would mean else block in while-else would be executed each time when condition is false.

    To ease your understanding think of it that way:

    Without break, return, etc., loop ends only when condition is no longer true and in such case else block will also execute once. In case of Python for you must consider C-style for loops (with conditions) or translate them to while.

    Another note:

    Premature break, return, etc. inside loop makes impossible for condition to become false because execution jumped out of the loop while condition was true and it would never come back to check it again.

    0 讨论(0)
  • 2020-11-21 07:34

    Here's a way to think about it that I haven't seen anyone else mention above:

    First, remember that for-loops are basically just syntactic sugar around while-loops. For example, the loop

    for item in sequence:
        do_something(item)
    

    can be rewritten (approximately) as

    item = None
    while sequence.hasnext():
        item = sequence.next()
        do_something(item)
    

    Second, remember that while-loops are basically just repeated if-blocks! You can always read a while-loop as "if this condition is true, execute the body, then come back and check again".

    So while/else makes perfect sense: It's the exact same structure as if/else, with the added functionality of looping until the condition becomes false instead of just checking the condition once.

    And then for/else makes perfect sense too: because all for-loops are just syntactic sugar on top of while-loops, you just need to figure out what the underlying while-loop's implicit conditional is, and then the else corresponds to when that condition becomes False.

    0 讨论(0)
  • 2020-11-21 07:37

    Codes in else statement block will be executed when the for loop was not be broke.

    for x in xrange(1,5):
        if x == 5:
            print 'find 5'
            break
    else:
        print 'can not find 5!'
    #can not find 5!
    

    From the docs: break and continue Statements, and else Clauses on Loops

    Loop statements may have an else clause; it is executed when the loop terminates through exhaustion of the list (with for) or when the condition becomes false (with while), but not when the loop is terminated by a break statement. This is exemplified by the following loop, which searches for prime numbers:

    >>> for n in range(2, 10):
    ...     for x in range(2, n):
    ...         if n % x == 0:
    ...             print(n, 'equals', x, '*', n//x)
    ...             break
    ...     else:
    ...         # loop fell through without finding a factor
    ...         print(n, 'is a prime number')
    ...
    2 is a prime number
    3 is a prime number
    4 equals 2 * 2
    5 is a prime number
    6 equals 2 * 3
    7 is a prime number
    8 equals 2 * 4
    9 equals 3 * 3
    

    (Yes, this is the correct code. Look closely: the else clause belongs to the for loop, not the if statement.)

    When used with a loop, the else clause has more in common with the else clause of a try statement than it does that of if statements: a try statement’s else clause runs when no exception occurs, and a loop’s else clause runs when no break occurs. For more on the try statement and exceptions, see Handling Exceptions.

    The continue statement, also borrowed from C, continues with the next iteration of the loop:

    >>> for num in range(2, 10):
    ...     if num % 2 == 0:
    ...         print("Found an even number", num)
    ...         continue
    ...     print("Found a number", num)
    Found an even number 2
    Found a number 3
    Found an even number 4
    Found a number 5
    Found an even number 6
    Found a number 7
    Found an even number 8
    Found a number 9
    
    0 讨论(0)
  • 2020-11-21 07:38

    Python uses an else after for and while loops so that if nothing applies to the loop, something else happens. For example:

    test = 3
    while test == 4:
         print("Hello")
    else:
         print("Hi")
    

    The output would be 'Hi' over and over again (if I'm correct).

    0 讨论(0)
  • 2020-11-21 07:40

    It's a strange construct even to seasoned Python coders. When used in conjunction with for-loops it basically means "find some item in the iterable, else if none was found do ...". As in:

    found_obj = None
    for obj in objects:
        if obj.key == search_key:
            found_obj = obj
            break
    else:
        print('No object found.')
    

    But anytime you see this construct, a better alternative is to either encapsulate the search in a function:

    def find_obj(search_key):
        for obj in objects:
            if obj.key == search_key:
                return obj
    

    Or use a list comprehension:

    matching_objs = [o for o in objects if o.key == search_key]
    if matching_objs:
        print('Found {}'.format(matching_objs[0]))
    else:
        print('No object found.')
    

    It is not semantically equivalent to the other two versions, but works good enough in non-performance critical code where it doesn't matter whether you iterate the whole list or not. Others may disagree, but I personally would avoid ever using the for-else or while-else blocks in production code.

    See also [Python-ideas] Summary of for...else threads

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