When you want to create a loop in Python, you generally have two choices: the while
loop and the for
loop. while
is simple: it just repeats until a given condition is no longer true. The for
loop is more complex, and thus more powerful: for
lets you iterate through objects in a collection of some kind without having to know details about the collection.
Python for loop components
A Python for
loop has two components:
- A container, sequence, or generator that contains or yields the elements to be looped over. In general, any object that supports Python’s iterator protocol can be used in a
for
loop. - A variable that holds each element from the container/sequence/generator.
In the following example, we loop through a list of numbers, and use the variable digit
to hold each number in turn:
for digit in [3,1,4,1,5,9]: print (digit)
This will print:
3 1 4 1 5 9
If you are iterating through an object that yields containers or sequences, you can use Python's multi-assignment syntax to unpack them. For instance:
for letter, number in [["a",1],["b",2]]: print (letter, number)
The output:
a 1 b 2
Common Python for loops
Here are some common objects used in a Python for loop:
Lists
The example above shows how a list can be iterated over using a for
loop. Note that if you have a list of lists, each element extracted by the for
loop will itself be a list. for
loops do not automatically “flatten” nested structures of any kind.
Strings
Strings in Python are considered “sequences” — they can be iterated over, and the results of iterating over a string are each character in the string.
for letter in "Hello world": print (letter)
This would yield:
H e l l o w o r l d
Dictionaries
Iterating through a dictionary with a for
loop yields each key in the dictionary.
d1 = { "a": 1, "b": 2 } for key in d1: print (key)
This would yield:
a b
If you want to iterate through the values of a dictionary, use the dictionary’s .values()
method. You can also iterate through keys and values together, with .items()
:
d1 = { "a": 1, "b": 2 } for key, value in d1.items(): print (key, value)
This would yield:
a 1 b 2
Generators
Generators yield a succession of items, one for each time they’re called. A common example of a generator used in a for
loop is range
.
for n in range(50): print (n)
This would print the numbers 0 through 49.
Note that just because you can use a generator in a for
loop doesn’t mean that the generator will eventually stop of its own accord. For instance, this for
loop will run forever:
def forever(): while True: yield 1 for n in forever(): print (n)
In such cases you may want to take steps to ensure the loop can terminate. (See “Flow control” below.)
Using indexes and enumerate with a Python for loop
Developers who come to Python from languages like C, C++, or Java will often create an index variable that is used to step through the object being iterated. An example:
x=[3,1,4,1,5,9] n = 0 while n<len(x): print (x[n]) n+=1
This isn’t wrong as such, but it misses the point of how Python works. A for
loop in Python doesn’t require an index; it can just traverse the object to be iterated over without needing to index into it.
However, sometimes you need to keep track of which element you’re dealing with while looping. Python’s enumerate()
utility helps with this. It takes an iterable and upon each iteration generates a tuple of the index and the object at that index:
x = [3,1,4,1,5,9] for index, n in enumerate(x): print (index, n)
0 3 1 1 2 4 3 1 4 5 5 9
Flow control in a Python for loop
for
loops don’t always run to completion, or in exact sequence. Sometimes you want to leave a for
loop early, or skip over an item in the loop. To do that, Python provides you with two keywords: break
and continue
.
for n in range(20): if n % 2 == 0: # if n is a multiple of 2 continue # then skip it # everything after this point is not run # if `continue` is invoked print (n) print ("Done")
This yields 1 3 5 7 9 11 13 15 17 19
, then Done
. Note that when the loop ends, the program continues normally at print ("Done")
.
for n in range(20): if n == 10: break # leave the loop altogether print (n) print ("Done")
This prints the numbers 0
through 9
, then Done
.
Note that if you have loops nested inside other loops, break
will only affect the current loop — it won't exit from all loop levels. Exiting from multiple for
loops requires a different mechanism, like a sentinel variable:
done = False for n in range(20): for m in range(40): if n==10 and m==10: done = True if done: break if done: break
A Python for loop gotcha
When iterating over the elements of an object in a for
loop, don’t do anything that would alter the members or length of the sequence. For instance, if you’re iterating over a list, don’t add or remove elements from the list as you iterate.
If the reason you’re iterating over elements is to test each element to see if you need to add or remove something, there is a better solution. Create a new, empty container, populate it only with the elements you want to keep, then replace the old container with the new one.
Here is an example with a list. This creates a new list that contains only odd numbers:
old_list = [1,2,3,4,5,6] new_list = [] for n in old_list: if n % 2: new_list.append(n) old_list = new_list