If you’re moving to Python from C or Java, you might be confused by Python’sfor
loops.Python doesn’t actually have for loops… at least not the same kind offor
loop that C-based languages have. Python’sfor
loops are actuallyforeach loops.
In this article I’ll compare Python’sfor
loops to those of other languages and discuss the usual ways we solve common problems withfor
loops in Python.
Before we look at Python’s loops, let’s take a look at a for loop in #"https://en.wikipedia.org/wiki/Foreach_loop">foreach).
This provides us with the index of each item in ourcolors
list, which is the same way that C-stylefor
loops work. To get the actual color, we usecolors[i]
.
Both the while loop and range-of-len methods rely on looping over indexes. But we don’t actually care about the indexes: we’re only using these indexes for the purpose of retrieving elements from our list.
Because we don’t actually care about the indexes in our loop, there isa much simpler method of looping we can use:
123 |
|
So instead of retrieving the item indexes and looking up each element, we can just loop over our list using a plain for-in loop.
The other two methods we discussed are sometimes referred to asanti-patterns because they are programming patterns which are widely considered unidiomatic.
What if we actually need the indexes? For example, let’s say we’re printing out president names along with their numbers (based on list indexes).
We could userange(len(our_list))
and then lookup the index like before:
123 |
|
But there’s a more idiomatic way to accomplish this task: use theenumerate
function.
Python’s built-inenumerate
function allows us to loop over a list and retrieve both the index and the value of each item in the list:
123 |
|
Theenumerate
function gives us an iterable where each element is a tuple that contains the index of the item and the original item value.
This function is meant for solving the task of:
So whenever we need item indexes while looping, we should think ofenumerate
.
Note: thestart=1
option toenumerate
here is optional. If we didn’t specify this, we’d start counting at0
by default.
Often when we use list indexes, it’s to look something up in another list.
For example, here we’re looping over two lists at the same time using indexes to look up corresponding elements:
12345 |
|
Note that we only need the index in this scenario because we’re using it to lookup elements at the same index in our second list. What we really want is to loop over two lists simultaneously: the indexes just provide a means to do that.
We don’t actually care about the index when looping here. Our real goal is to loop over two lists at once. This need is common enough that there’s a special built-in function just for this.
Python’szip
function allows us toloop over multiple lists at the same time:
1234 |
|
Thezip
function takes multiple lists and returns an iterable that provides a tuple of the corresponding elements of each list as we loop over it.
Note thatzip
with different size lists will stop after the shortest list runs out of items. You may want to look intoitertools.zip_longest if you need different behavior. Also note thatzip
in Python 2 returns a list butzip
in Python 3 returns a lazy iterable. In Python 2,itertools.izip
is equivalent to the newer Python 3zip
function.
Here’s a very short looping cheat sheet that might help you remember the preferred construct for each of these three looping scenarios.
Loop over a single list with a regular for-in:
12 |
|
Loop over multiple lists at the same time withzip
:
12 |
|
Loop over a list while keeping track of indexes withenumerate
:
12 |
|
If you find yourself tempted to userange(len(my_list))
or a loop counter, think about whether you can reframe your problem to allow usage ofzip
orenumerate
(or a combination of the two).
In fact, if you find yourself reaching forenumerate
, think about whether you actually need indexes at all. It’s quite rare to need indexes in Python.
zip
enumerate
If you find yourself struggling to figure out the best way to loop, try using the cheat sheet above.
You don’t learn by putting information in your head, you learn by attempting to retrieve information from your head.So you’ve just read an article on something new, but you haven’t learned yet.
Write some code that usesenumerate
andzip
later today and then quiz yourself tomorrow on the different ways of looping in Python.You have to practice these skills if you want to actually remember them.
If you’d like toget hands-on experience practicing Python every week, I have a Python skill-building service you should consider joining.If you sign up for Python Morsels I’ll give you aPython looping exercise that right now and then I’ll send youone new Python exercise every week after that.
Fill out the form above tosign up forPython Morsels,get some practice with thezip
function, and start leveling-up your Python skills every week.
Hi! My name is Trey Hunner.
I help Python teamswrite better Python code throughPython team training.
I also help individualslevel-up their Python skills withweekly Python skill-building.
Python Team TrainingNeed to fill ingaps in your Python knowledge? I have just the thing.
Intro to Python courses often skip over certainfundamental Python concepts. I send emails meant help you internalize those concepts without wasting time.
This isn't an Intro to Python course. It'sPython conceptsbeyond Intro to Python. Sign up below to get started.
Intro to Python courses often skip over somefundamental Python concepts.
Sign up below and I'll share ideasnew Pythonistas often overlook.
You're nearly signed up. You just need tocheck your email and click the link there toset your password.
Right after you've set your password you'll receive your first Python Morsels exercise.