Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I understand how this construct works:

for i in range(10):     print(i)      if i == 9:         print("Too big - I'm giving up!")         break else:     print("Completed successfully") 

But I don't understand why else is used as the keyword here, since it suggests the code in question only runs if the for block does not complete, which is the opposite of what it does! No matter how I think about it, my brain can't progress seamlessly from the for statement to the else block. To me, continue or continuewith would make more sense (and I'm trying to train myself to read it as such).

I'm wondering how Python coders read this construct in their head (or aloud, if you like). Perhaps I'm missing something that would make such code blocks more easily decipherable?

like image 257
Kent Boogaart Avatar asked Apr 02 '12 16:04

Kent Boogaart


People also ask

Why we use else with while loop in Python?

Using else Statement with While Loop Python supports to have an else statement associated with a loop statement. If the else statement is used with a while loop, the else statement is executed when the condition becomes false.

What is the use of else in for and while loop?

While loop with elseThe else part is executed if the condition in the while loop evaluates to False . The while loop can be terminated with a break statement. In such cases, the else part is ignored. Hence, a while loop's else part runs if no break occurs and the condition is false.

Does a while loop need an else?

The while statement allows you to repeatedly execute a block of statements as long as a condition is true. A while statement is an example of what is called a looping statement. A while statement can have an optional else clause.

What is for else and while else in Python?

What is For Else and While Else in Python? For-else and while-else are useful features provided by Python. In simple words, you can use the else block just after the for and while loop. Else block will be executed only if the loop isn't terminated by a break statement.


2 Answers

A common construct is to run a loop until something is found and then to break out of the loop. The problem is that if I break out of the loop or the loop ends I need to determine which case happened. One method is to create a flag or store variable that will let me do a second test to see how the loop was exited.

For example assume that I need to search through a list and process each item until a flag item is found and then stop processing. If the flag item is missing then an exception needs to be raised.

Using the Python for...else construct you have

for i in mylist:     if i == theflag:         break     process(i) else:     raise ValueError("List argument missing terminal flag.") 

Compare this to a method that does not use this syntactic sugar:

flagfound = False for i in mylist:     if i == theflag:         flagfound = True         break     process(i)  if not flagfound:     raise ValueError("List argument missing terminal flag.") 

In the first case the raise is bound tightly to the for loop it works with. In the second the binding is not as strong and errors may be introduced during maintenance.

like image 181
Lance Helsten Avatar answered Sep 23 '22 19:09

Lance Helsten


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

like image 44
Björn Lindqvist Avatar answered Sep 25 '22 19:09

Björn Lindqvist