zip() in Python: Get elements from multiple lists

Modified: | Tags: Python, List

In Python, the built-in function zip() aggregates multiple iterable objects such as lists and tuples. You can iterate over multiple lists simultaneously in a for loop using zip().

See the following article for information on compressing and decompressing ZIP files.

Iterate two, three, or more lists with zip()

By passing two lists to zip(), you can iterate over them simultaneously in a for loop.

names = ['Alice', 'Bob', 'Charlie']
ages = [24, 50, 18]

for name, age in zip(names, ages):
    print(name, age)
# Alice 24
# Bob 50
# Charlie 18

This also applies to three or more lists.

points = [100, 85, 90]

for name, age, point in zip(names, ages, points):
    print(name, age, point)
# Alice 24 100
# Bob 50 85
# Charlie 18 90

You can also use other iterable objects, such as tuples, with zip().

In the case that number of elements is different

zip() ignores the extra elements

If the iterable objects have different numbers of elements, zip() ignores the extra elements.

names = ['Alice', 'Bob', 'Charlie', 'Dave']
ages = [24, 50, 18]

for name, age in zip(names, ages):
    print(name, age)
# Alice 24
# Bob 50
# Charlie 18

The strict parameter of zip() (Python3.10 or later)

The strict parameter was added to zip() in Python 3.10. Note that it is not available in 3.9 or earlier.

If strict=True, an error is raised if the number of elements is different.

# for name, age in zip(names, ages, strict=True):
#     print(name, age)
# ValueError: zip() argument 2 is shorter than argument 1

The default value is strict=False, which maintains the same behavior as in Python 3.9 and earlier versions, where extra elements are ignored.

itertools.zip_longest() fills in the missing elements

With itertools.zip_longest(), you can fill the missing elements with any values.

By default, it is filled with None.

from itertools import zip_longest

names = ['Alice', 'Bob', 'Charlie', 'Dave']
ages = [24, 50, 18]

for name, age in zip_longest(names, ages):
    print(name, age)
# Alice 24
# Bob 50
# Charlie 18
# Dave None

You can specify the value to fill in the fillvalue parameter.

for name, age in zip_longest(names, ages, fillvalue=20):
    print(name, age)
# Alice 24
# Bob 50
# Charlie 18
# Dave 20

The same fill value is applied to all lists, even if there are multiple lists with missing elements. You cannot specify different fill values for each list.

points = [100, 85]

for name, age, point in zip_longest(names, ages, points, fillvalue=20):
    print(name, age, point)
# Alice 24 100
# Bob 50 85
# Charlie 18 20
# Dave 20 20

To fill multiple lists with unknown numbers of elements using different fill values, follow these steps:

  1. Define the value to fill for all lists
  2. Get the maximum number of elements
  3. Fill all lists up to the maximum number of elements
  4. Aggregate with zip()
fill_name = 'XXX'
fill_age = 20
fill_point = 50

len_names = len(names)
len_ages = len(ages)
len_points = len(points)

max_len = max(len_names, len_ages, len_points)

names = names + [fill_name] * (max_len - len_names)
ages = ages + [fill_age] * (max_len - len_ages)
points = points + [fill_point] * (max_len - len_points)

print(names)
print(ages)
print(points)
# ['Alice', 'Bob', 'Charlie', 'Dave']
# [24, 50, 18, 20]
# [100, 85, 50, 50]

for name, age, point in zip(names, ages, points):
    print(name, age, point)
# Alice 24 100
# Bob 50 85
# Charlie 18 50
# Dave 20 50

Filling the list to the maximum number of elements involves initializing and concatenating lists.

It can be a function like this:

def my_zip_longest(iterables, fillvalues):
    max_len = max(len(i) for i in iterables)
    return zip(*[list(i) + [v] * (max_len - len(i)) for i, v in zip(iterables, fillvalues)])

for name, age, point in my_zip_longest((names, ages, points), ('XXX', 20, 50)):
    print(name, age, point)
# Alice 24 100
# Bob 50 85
# Charlie 18 50
# Dave 20 50

It uses list comprehensions and list unpacking by *.

Get a list of multiple iterable elements

zip returns an iterator (zip object) that contains tuple with the elements of multiple iterable objects.

names = ['Alice', 'Bob', 'Charlie']
ages = (24, 50, 18)

z = zip(names, ages)
print(z)
print(type(z))
# <zip object at 0x1038b0980>
# <class 'zip'>

It can be converted to a list with list().

l = list(zip(names, ages))
print(l)
print(type(l))
print(type(l[0]))
# [('Alice', 24), ('Bob', 50), ('Charlie', 18)]
# <class 'list'>
# <class 'tuple'>

Related Categories

Related Articles