Чи існує функція, схожа на блискавку, яка прокладає найбільшу довжину в Python?


170

Чи є вбудована функція, яка працює на зразок, 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)]

Відповіді:


243

У 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)]

3
Чи не маємо рішення, яке не має itertools Python 3?
PascalVKooten

3
@PascalvKooten це не потрібно. itertoolsв будь-якому випадку є вбудованим модулем С.
Антті Хаапала

82

Для Python 2.6x використовуйте itertoolsмодулі izip_longest.

Для Python 3 використовуйте zip_longestнатомість (без ведучих i).

>>> list(itertools.izip_longest(a, b, c))
[('a1', 'b1', 'c1'), (None, 'b2', 'c2'), (None, 'b3', None)]

8
Якщо ви хочете зробити свій код і python 2, і python 3 сумісним, ви можете використовувати six.moves.zip_longestзамість цього.
Гамрікс

5

рішення не для 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)

2

рішення не для itertools My Python 2:

if len(list1) < len(list2):
    list1.extend([None] * (len(list2) - len(list1)))
else:
    list2.extend([None] * (len(list1) - len(list2)))

0

Я використовую 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]

2
Будь ласка, додайте пояснення, чому цей код працює. Або чому це правильна відповідь
Suit Boy Apps
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.