In Python, a for
loop is usually written as a loop over an iterable object. This means you don’t need a counting variable to access items in the iterable. Sometimes, though, you do want to have a variable that changes on each loop iteration. Rather than creating and incrementing a variable yourself, you can use Python’s enumerate()
to get a counter and the value from the iterable at the same time!
In this tutorial, you’ll see how to:
- Use
enumerate()
to get a counter in a loop - Apply
enumerate()
to display item counts - Use
enumerate()
with conditional statements - Implement your own equivalent function to
enumerate()
- Unpack values returned by
enumerate()
Let’s get started!
Free Download: Get a sample chapter from CPython Internals: Your Guide to the Python 3 Interpreter showing you how to unlock the inner workings of the Python language, compile the Python interpreter from source code, and participate in the development of CPython.
Iterating With for
Loops in Python
A for
loop in Python uses collection-based iteration. This means that Python assigns the next item from an iterable to the loop variable on every iteration, like in this example:
>>> values = ["a", "b", "c"]
>>> for value in values:
... print(value)
...
a
b
c
In this example, values
is a list with three strings, "a"
, "b"
, and "c"
. In Python, lists are one type of iterable object. In the for
loop, the loop variable is value
. On each iteration of the loop, value
is set to the next item from values
.
Next, you print value
onto the screen. The advantage of collection-based iteration is that it helps avoid the off-by-one error that is common in other programming languages.
Now imagine that, in addition to the value itself, you want to print the index of the item in the list to the screen on every iteration. One way to approach this task is to create a variable to store the index and update it on each iteration:
>>> index = 0
>>> for value in values:
... print(index, value)
... index += 1
...
0 a
1 b
2 c
In this example, index
is an integer that keeps track of how far into the list you are. On each iteration of the loop, you print index
as well as value
. The last step in the loop is to update the number stored in index
by one. A common bug occurs when you forget to update index
on each iteration:
>>> index = 0
>>> for value in values:
... print(index, value)
...
0 a
0 b
0 c
In this example, index
stays at 0
on every iteration because there’s no code to update its value at the end of the loop. Particularly for long or complicated loops, this kind of bug is notoriously hard to track down.
Another common way to approach this problem is to use range()
combined with len()
to create an index automatically. This way, you don’t need to remember to update the index:
>>> for index in range(len(values)):
... value = values[index]
... print(index, value)
...
0 a
1 b
2 c
In this example, len(values)
returns the length of values
, which is 3
. Then range()
creates an iterator running from the default starting value of 0
until it reaches len(values)
minus one. In this case, index
becomes your loop variable. In the loop, you set value
equal to the item in values
at the current value of index
. Finally, you print index
and value
.
With this example, one common bug that can occur is when you forget to update value
at the beginning of each iteration. This is similar to the previous bug of forgetting to update the index. This is one reason that this loop isn’t considered Pythonic.
This example is also somewhat restricted because values
has to allow access to its items using integer indices. Iterables that allow this kind of access are called sequences in Python.
Technical Detail: According to the Python documentation, an iterable is any object that can return its members one at a time. By definition, iterables support the iterator protocol, which specifies how object members are returned when an object is used in an iterator. Python has two commonly used types of iterables:
Any iterable can be used in a for
loop, but only sequences can be accessed by integer indices. Trying to access items by index from a generator or an iterator will raise a TypeError
:
>>> enum = enumerate(values)
>>> enum[0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'enumerate' object is not subscriptable
In this example, you assign the return value of enumerate()
to enum
. enumerate()
is an iterator, so attempting to access its values by index raises a TypeError
.
Fortunately, Python’s enumerate()
lets you avoid all these problems. It’s a built-in function, which means that it’s been available in every version of Python since it was added in Python 2.3, way back in 2003.
Using Python’s enumerate()
You can use enumerate()
in a loop in almost the same way that you use the original iterable object. Instead of putting the iterable directly after in
in the for
loop, you put it inside the parentheses of enumerate()
. You also have to change the loop variable a little bit, as shown in this example:
>>> for count, value in enumerate(values):
... print(count, value)
...
0 a
1 b
2 c
Read the full article at https://realpython.com/python-enumerate/ »
[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]
from Real Python
read more
No comments:
Post a Comment