zip() in Python: Get elements from multiple lists
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:
- Define the value to fill for all lists
- Get the maximum number of elements
- Fill all lists up to the maximum number of elements
- 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.
- Initialize a list with given size and values in Python
- Add an item to a list in Python (append, extend, insert)
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'>