note.nkmk.me

zip() in Python: Get elements from multiple lists

Posted: 2020-08-27 / Tags: Python, List

In Python, the built-in function zip() aggregates the elements from multiple iterable objects (lists, tuples, etc.). It is used when iterating multiple list elements in a for loop.

Contents:

  • Get elements from multiple lists in for loop
  • In the case that number of elements is different
    • zip() ignores the extra elements
    • itertools.zip_longest() fills in the missing elements
  • Get a list of multiple iterable elements
Sponsored Link

Get elements from multiple lists in for loop

By passing an iterable object (lists, tuples, etc.) as an argument of zip(), multiple elements can be obtained simultaneously in the 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

The same applies not only to two, but also to three or more.

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

In the case that number of elements is different

zip() ignores the extra elements

When the number of elements of each iterable object is different, 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

itertools.zip_longest() fills in the missing elements

By itertools.zip_longest(), you can fill the missing elements with arbitrary 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 argument fillvalue.

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

The value to be filled is uniform even if there are multiple lists with insufficient elements. You can't specify different values.

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

If you want to fill multiple lists with unknown numbers of elements with different values, follow the procedure below.

  1. Define the value to fill for all lists
  2. Get maximum number of elements
  3. Fill all lists up to 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

The process of filling the list to the maximum number of elements uses initialization and concatenation of 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 expansion by *.

Sponsored Link

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 0x10b57b888>
# <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'>
Sponsored Link
Share

Related Categories

Related Posts