Tip 17 Avoid range() in Loops

Pythonic Programming — by Dmitry Zinoviev (26 / 116)

The Pragmatic Programmers
The Pragmatic Programmers

--

👈 Pickle It | TOC | Pass It 👉

★★2.7, 3.4+ The well-known built-in function range that they very likely taught you to use in a for loop is often unnecessary. It is a tribute to C/C++/Java, the honorable predecessors of Python that actually need an index loop variable. Python does not. Here is why.

The “classic” non-destructive for loop over an iterable seq looks like this:

​ ​for​ i ​in​ range(len(seq)):
​ do_something_with(seq[i])

The variable i is used only to access the next element from the iterable. Since Python for loop is, in fact, a foreach loop, there is a better way to accomplish this by iterating directly over the iterable (thus the name):

​ ​for​ item ​in​ seq:
​ do_something_with(item)

The direct iteration approach is faster (by about 30%), does not require creating the unnecessary indexes, and is more readable (“for [each] item in [that] sequence, do something with [that] item”). But what if you really need to know the index — say, to modify each item in a mutable iterable? For that, you have the built-in function enumerate. The function returns a generator (Tip 58, Yield, Do Not Return) that produces tuples of items and their respective indexes in the form (i,seq[i]).

​ ​for​ i, item ​in​ enumerate(seq):
​ seq[i] = do_something_with(item)

--

--

The Pragmatic Programmers
The Pragmatic Programmers

We create timely, practical books and learning resources on classic and cutting-edge topics to help you practice your craft and accelerate your career.