类似于zip()的内置函数,使用无值从左开始填充不相等的长度

时间:2018-08-16 13:33:26

标签: python python-3.x itertools built-in

是否有一个内置函数,其功能类似于zip(),但会填充结果,以便结果列表的长度为最长输入的长度,并从左起填充列表与例如None

已经有itertools模块中的answer使用zip_longest,相应的question与此非常相似。但是使用zip_longest似乎只能填充右边的缺失数据。

这可能是一个用例,假设我们仅以这种方式存储名称(这只是一个示例):

header = ["title", "firstname", "lastname"]
person_1 = ["Dr.", "Joe", "Doe"]
person_2 = ["Mary", "Poppins"]
person_3 = ["Smith"]

没有其他排列方式,例如(["Poppins", "Mary"]["Poppins", "Dr", "Mary"])等。

如何使用内置函数获得类似结果?

>>> dict(magic_zip(header, person_1))
{'title': 'Dr.', 'lastname': 'Doe', 'firstname': 'Joe'}
>>> dict(magic_zip(header, person_2))
{'title': None, 'lastname': 'Poppins', 'firstname': 'Mary'}
>>> dict(magic_zip(header, person_3))
{'title': None, 'lastname': 'Smith', 'firstname': None}

4 个答案:

答案 0 :(得分:5)

使用 zip_longest ,但使用反向列表。

示例

from itertools import zip_longest

header = ["title", "firstname", "lastname"]
person_1 = ["Dr.", "Joe", "Doe"]
person_2 = ["Mary", "Poppins"]
person_3 = ["Smith"]

print(dict(zip_longest(reversed(header), reversed(person_2))))
# {'lastname': 'Poppins', 'firstname': 'Mary', 'title': None}

关于您的用例:

>>> dict(zip_longest(reversed(header), reversed(person_1))) 
{'title': 'Dr.', 'lastname': 'Doe', 'firstname': 'Joe'}
>>> dict(zip_longest(reversed(header), reversed(person_2)))
{'lastname': 'Poppins', 'firstname': 'Mary', 'title': None} 
>>> dict(zip_longest(reversed(header), reversed(person_3))) 
{'lastname': 'Smith', 'firstname': None, 'title': None}

答案 1 :(得分:5)

只需使用zip_longest并以相反的方向读取参数:

In [20]: dict(zip_longest(header[::-1], person_1[::-1]))
Out[20]: {'lastname': 'Doe', 'firstname': 'Joe', 'title': 'Dr.'}

In [21]: dict(zip_longest(header[::-1], person_2[::-1]))
Out[21]: {'lastname': 'Poppins', 'firstname': 'Mary', 'title': None}

In [22]: dict(zip_longest(header[::-1], person_3[::-1]))
Out[22]: {'lastname': 'Smith', 'firstname': None, 'title': None}

由于zip *函数需要能够在常规可迭代对象上使用,因此它们不支持“从左开始”填充,因为您需要先穷尽可迭代对象。在这里,我们可以自己翻转事物。

答案 2 :(得分:2)

具有可变数量args的通用“ magic zip”生成器函数(仅使用惰性求值函数,并且没有python循环):

import itertools

def magic_zip(*args):
    return itertools.zip_longest(*map(reversed,args))

测试(当然,如果是字典构建,则仅需要2个参数):

for p in (person_1,person_2,person_3):
    print(dict(magic_zip(header,p)))

结果:

{'lastname': 'Doe', 'title': 'Dr.', 'firstname': 'Joe'}
{'lastname': 'Poppins', 'title': None, 'firstname': 'Mary'}
{'lastname': 'Smith', 'title': None, 'firstname': None}

答案 3 :(得分:1)

def magic_zip(*lists):
    max_len = max(map(len, lists))
    return zip(*([None] * (max_len - len(l)) + l for l in lists))