Python, 使用 zip() 函数。一次性获得多个列表的元素

商业

Python 的内置函数 zip() 结合了多个可迭代对象 (列表、图元等) 的元素,用于在一个 for 循环中检索多个列表的元素。

本节描述了zip()函数的以下用法。

  • 在一个for循环中获取多个列表的元素。
  • 处理不同数量的元素
    • zip():该函数将忽略那些过多的元素。
    • itertools.zip_longest():这个函数将填补缺失的元素。
  • 获取一个由多个迭代器的元素组成的图元列表。

在一个for循环中获取多个列表的元素。

如果你想在一个for循环中同时检索和使用多个可迭代对象(列表、图元等)的元素,请将它们指定为zip()函数的参数。

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

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

不仅仅是两个,还有三个或更多。

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

处理不同数量的元素

zip()函数忽略了大量的元素。

在zip()函数中,如果每个列表中的元素数量不同,最多返回较少(较短)的元素数量,而较大的数量将被忽略。

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()函数将填补缺少的元素。

使用标准库itertools模块中的zip_longest(),当每个列表中的元素数量不同时,可以用任意的值来填补缺少的元素。

默认情况下,它被填充为无。

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

如果指定了fillvalue参数,它将被填入该值。

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

即使有多个缺失元素的列表,要填充的值也是统一的。不可能指定不同的值。

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

可以通过在zip_longest()里面使用zip_longest()来指定一个不同的值,但是这并不实用,因为你需要事先知道列表中哪些元素被遗漏了。

如果你想用未知数量的元素填充多个列表,每个元素都有不同的值,可以考虑采用以下程序。

  1. 定义要为所有列表填充的值。
  2. 获取最大数量的元素
  3. 将所有列表填充到最大的元素数
  4. 使用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

在填充到最大数量的元素的过程中,我们做了以下工作。

  • 用一个任意的值和元素数初始化一个列表
  • +运算符,将列表连接在一起

如果我们把它变成一个函数,它看起来像这样。原始列表和填充该列表的值分别被指定为iterables(列表或元组)参数。

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

它使用列表理解符号和列表扩展的*。

获取一个由多个迭代器的元素组成的图元列表。

zip()函数返回一个迭代器(zip对象),该迭代器是多个可迭代对象的元素的一个元组。
它也可以在for循环之外使用,而且目标不限于列表。

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

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

如果你想获得一个由多个可迭代对象的元素组成的元组列表,使用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'>
Copied title and URL