Improve Your Python Code by Using the Built-in enumerate() Function
And discover why using it will help to make your code more readable and more efficient!
Python has many built-in functions [1] that are not used enough at all. As explained in this article, using them has several advantages, mainly on the readability and the efficiency of your Python codes. This article focuses on the enumerate
built-in function which is used to iterate sequences.
Iterating sequences
When iterating through the elements of a sequence, and if you need both the index and the value of the element, the classical way to proceed inspired by traditional imperative programming languages such as C is as follows:
def seq_to_str_1(data):
result = ''
i = 0
while i < len(data):
result += f'{i}: {data[i]}\n'
i += 1
return result[:-1]
In this example, a loop is executed from i = 0
to the length of the data
sequence minus one. For each element in data
, its position in the sequence and its value are retrieved and added to the result
string variable.
This first example is not very Pythonic, it is just like a C programmer wrote his/her first Python program! The code can be improved a bit by using a for
statement instead of a while
loop:
def seq_to_str_2(data):
result = ''
for i in range(len(data)):
result += f'{i}: {data[i]}\n'
return result[:-1]
Using the enumerate() built-in function
It is possible to do even better by using the enumerate
built-in function [2], which creates an iterator of tuples whose elements each contain both the index and the corresponding value of the iterated sequence elements. The previous code can be rewritten as follows:
def seq_to_str_3(data):
result = ''
for (i, value) in enumerate(data):
result += f'{i}: {value}\n'
return result[:-1]
This third version of the seq_to_str
function is the most Pythonic one. It also benefits from the strengths of two features of Python:
- The
enumerate
built-in function creates an enumerate object, which is a sequence whose elements are lazily generated. This may improve the memory consumption of your program. - Also, the
for
loop with which theenumerate
function should be used is way more efficient than a classicalwhile
loop to go through the elements of an iterable object.
The enumerate
function also accepts a second optional parameter that can be set to start the enumeration, not from the first element (index 0), but any other one. It can also be used with any other objects that are iterable, and not only with sequences [3].
Comparing the three approaches
The third version of the seq_to_str
function is clearly the winner. The first advantage is that using the enumerate
function improved the readability of the code. A reader can quickly grasp what the purpose of the code is, focusing on the “what it does” and not on the “how it does it”.
A second win is a possible better execution time. For example, on my old 2012 MacBook Pro computer, calling the three versions of the function with a 100.000-element list gives the following average execution times: 141 ms, 119 ms, and 109 ms. The third version resulted in a 23% faster code.
Finally, the last advantage is related to memory consumption. If the loop does not aim at necessarily examining all the elements of the iterated sequence, some memory may be spared thanks to the lazy generation.
To conclude, if you want to master the Python programming language and write Pythonic and efficient codes, theenumerate
built-in function is clearly a string you need to add to your bow!
References
[1] Python Software Foundation, Built-in Functions — Python 3.9.5 Documentation, retrieved on June 14, 2021.
[2] Raymond Hettinger (2002), PEP 279 -- The enumerate() built-in function, Python.org.
[3] Python Software Foundation, Documentation of the enumerate function, retrieved on June 14, 2021.
More content at plainenglish.io