For loops in Python are one of many features that make Python so popular; they’re as close to plain English as you can get when writing software. They generally look like this:
for element in iterable:
# do things with element
What is an iterable? According to the Python docs an iterable is:
An object capable of returning its members one at a time. Examples of iterables include all sequence types (such as
list
,str
, andtuple
) and some non-sequence types likedict
, file objects, …
In other words, an “iterable” is a “thing that can be looped through”.
Let’s do some examples.
Python “for in” loop
This very English-sounding for loop construction is one of the reasons I love Python. It will perform a single iteration for
each element in
your iterable:
# lists
for num in [1, 2, 3]:
print(num)
# 1
# 2
# 3
Most iterable types work exactly how you’d expect:
# sets
for num in set([1, 2, 3]):
print(num)
# 1
# 2
# 3
Even strings work the same:
# strings
for letter in "abc":
print(letter)
# a
# b
# c
The continue statement
Similar to many other languages, continue
will skip to the next iteration of a loop:
for num in [1, 2, 3, 4]:
if num == 3:
continue
print(num)
# 1
# 2
# 4
The break statement
The break
statement does what its name implies, breaks the loop:
for num in [1, 2, 3, 4]:
if num == 3:
break
print(num)
# 1
# 2
If you have nested for loops, break
will only break the innermost loop:
def nested():
for num in [1, 2, 3]:
for char in "abc":
if char == "b":
break
print(num, char)
# We won't see 'b' or 'c'
# since we 'break' before printing 'b'
nested()
# 1 a
# 2 a
# 3 a
The else statement
In a for loop, else
will execute code at the end of the loop:
def loop_with_else():
for num in [1, 2, 3]:
print(num)
else:
print("else block")
print("done")
loop_with_else()
# 1
# 2
# 3
# "else block"
# "done"
However, the else block will not execute if you have a break
or return
statement inside your loop:
def loop_with_else():
for num in [1, 2, 3]:
if num == 2:
break
print(num)
else:
print("else block")
print("done")
loop_with_else()
# 1
# "done"
Return from within for loops
Another way to break out of for loops is via the return
keyword. Unlike break
, return
will break out of all loops contained within its parent function:
def nested():
for num in [1, 2, 3]:
for char in "abc":
if char == "b":
return "returned"
print(num, char)
# We won't see numbers 2 or 3
# Since we return at loop 1,b
nested()
# 1 a
"returned"
Python for loop with dicts
Looping through dicts
might require a small tweak. By default, using for in
with a dictionary will only get you the keys:
my_dict = {"first_name": "justin", "last_name": "joyce"}
for thing in my_dict:
print(thing)
# first_name
# last_name
However, this is an often-used pattern with dictionaries, and with one small addition we can access both keys and valuesโwe need dict.items()
:
my_dict = {"first_name": "justin", "last_name": "joyce"}
for k, v in my_dict.items():
print(f"Key is: {k}, Value is: {v}")
# Key is: first_name, Value is: justin
# Key is: last_name, Value is: joyce
This is exactly how you can invert a Python object, which I cover in another post.
Looping with the range function
You’ll sometimes see examples using python’s range()
builtin function:
for x in range(3):
print(x)
# 0
# 1
# 2
Using range
is less common than the for in
structure in my experience, but you’ll see both.
Unpacking nested iterables
Unpacking nested iterables within a single statement like this might not be the best idea, but Python will allow it:
def unpacking():
for num, char in [(1, "a"), (2, "b"), (3, "c")]:
print(num, char)
unpacking()
# 1 a
# 2 b
# 3 c
If you find yourself doing this you might want to consider refactoringโthis kind of thing gets confusing quickly.
Helpful Links
- Definition of iterable – Python docs
- Swapping dict keys and values in Python – me!