Python: zip-подобная функция, увеличивающая длину?
Есть ли встроенная функция, которая работает как zip()
, но будет обрабатывать результаты так, чтобы длина результирующего списка была длиной самого длинного ввода, а не кратчайшего ввода?
>>> a=['a1']
>>> b=['b1','b2','b3']
>>> c=['c1','c2']
>>> zip(a,b,c)
[('a1', 'b1', 'c1')]
>>> What command goes here?
[('a1', 'b1', 'c1'), (None, 'b2', 'c2'), (None, 'b3', None)]
Ответы
Ответ 1
В Python 3 вы можете использовать itertools.zip_longest
>>> list(itertools.zip_longest(a, b, c))
[('a1', 'b1', 'c1'), (None, 'b2', 'c2'), (None, 'b3', None)]
Вы можете использовать другое значение, отличное от None
, используя параметр fillvalue
:
>>> list(itertools.zip_longest(a, b, c, fillvalue='foo'))
[('a1', 'b1', 'c1'), ('foo', 'b2', 'c2'), ('foo', 'b3', 'foo')]
С Python 2 вы можете использовать itertools.izip_longest
(Python 2. 6+), или вы можете использовать map
с None
. Это немного известная функция map
(но map
изменена в Python 3.x, поэтому это работает только в Python 2.x).
>>> map(None, a, b, c)
[('a1', 'b1', 'c1'), (None, 'b2', 'c2'), (None, 'b3', None)]
Ответ 2
Для Python 2.6x используйте itertools
module izip_longest
.
Для Python 3 вместо zip_longest
(нет ведущего i
).
>>> list(itertools.izip_longest(a, b, c))
[('a1', 'b1', 'c1'), (None, 'b2', 'c2'), (None, 'b3', None)]
Ответ 3
non itertools Решение Python 3:
def zip_longest(*lists):
def g(l):
for item in l:
yield item
while True:
yield None
gens = [g(l) for l in lists]
for _ in range(max(map(len, lists))):
yield tuple(next(g) for g in gens)
Ответ 4
Решение, не относящееся к itertools My Python 2:
if len(list1) < len(list2):
list1.extend([None] * (len(list2) - len(list1)))
else:
list2.extend([None] * (len(list1) - len(list2)))
Ответ 5
Я использую 2d массив, но концепция похожа на Python 2.x:
if len(set([len(p) for p in printer])) > 1:
printer = [column+['']*(max([len(p) for p in printer])-len(column)) for column in printer]