Có một chức năng giống như zip để đệm cho chiều dài dài nhất trong Python?


170

Có một hàm tích hợp hoạt động như thế nào zip()nhưng nó sẽ đệm các kết quả sao cho độ dài của danh sách kết quả là độ dài của đầu vào dài nhất thay vì đầu vào ngắn nhất ?

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

Câu trả lời:


243

Trong Python 3 bạn có thể sử dụng itertools.zip_longest

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

Bạn có thể đệm với một giá trị khác với Nonebằng cách sử dụng fillvaluetham số:

>>> list(itertools.zip_longest(a, b, c, fillvalue='foo'))
[('a1', 'b1', 'c1'), ('foo', 'b2', 'c2'), ('foo', 'b3', 'foo')]

Với Python 2, bạn có thể sử dụng itertools.izip_longest(Python 2.6+) hoặc bạn có thể sử dụng mapvới None. Đây là một tính năngmap ít được biết đến của (nhưng mapđã thay đổi trong Python 3.x, vì vậy điều này chỉ hoạt động trong Python 2.x).

>>> map(None, a, b, c)
[('a1', 'b1', 'c1'), (None, 'b2', 'c2'), (None, 'b3', None)]

3
Chúng ta không có giải pháp Python 3 không itertools?
PascalVKooten

3
@PascalvKooten không bắt buộc. itertoolslà một mô-đun C dựng sẵn nào.
Antti Haapala

82

Đối với Python 2.6x, hãy sử dụng itertoolsmô-đun izip_longest.

Đối với Python 3 sử dụng zip_longestthay thế (không có hàng đầu i).

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

8
Trong trường hợp bạn muốn làm cho mã của mình tương thích cả python 2 và python 3, bạn có thể sử dụng six.moves.zip_longestthay thế.
Gamrix

5

giải pháp Python 3 không itertools:

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

non itertools Giải pháp Python 2 của tôi:

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

0

Tôi đang sử dụng mảng 2d nhưng khái niệm này tương tự với 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
Vui lòng thêm một lời giải thích tại sao mã này hoạt động. Hoặc tại sao đó là câu trả lời đúng
Ứng dụng Suit Boy
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.