Skip to content
derpx06Notes on systems, models & learning
5. Data Work · lesson 16 of 17 · 1 min · January 1, 2024

Iterators & Zip

enumerate, zip, and argument unpacking.

Not infrequently, you’ll want to iterate over a list and use both its elements and their indexes:

not_pythonic.py
# not Pythonic
for i in range(len(documents)):
  document = documents[i]
  do_something(i, document)

# also not Pythonic
i = 0
for document in documents:
  do_something(i, document)
  i += 1

The Pythonic solution is enumerate, which produces tuples (index, element):

enumerate.py
for i, document in enumerate(documents):
  do_something(i, document)

Similarly, if we just want the indexes:

indexes.py
for i in range(len(documents)): do_something(i)   # not Pythonic
for i, _ in enumerate(documents): do_something(i) # Pythonic

We’ll use this a lot.

Often we will need to zip two or more lists together. zip transforms multiple lists into a single list of tuples of corresponding elements:

zip.py
list1 = ['a', 'b', 'c']
list2 = [1, 2, 3]
zip(list1, list2)   # is [('a', 1), ('b', 2), ('c', 3)]

If the lists are different lengths, zip stops as soon as the first list ends.

You can also "unzip" a list using a strange trick:

unzip.py
pairs = [('a', 1), ('b', 2), ('c', 3)]
letters, numbers = zip(*pairs)

The asterisk performs argument unpacking, which uses the elements of pairs as individual arguments to zip. It ends up the same as if you’d called:

zipping_tuples.py
zip(('a', 1), ('b', 2), ('c', 3))

which returns [('a','b','c'), ('1','2','3')].

You can use argument unpacking with any function:

unpacking.py
def add(a, b): return a + b

add(1, 2)       # returns 3
add([1, 2])     # TypeError!
add(*[1, 2])    # returns 3

It is rare that we’ll find this useful, but when we do it’s a neat trick.