Apakah ada fungsi mirip zip yang panjangnya terpanjang dengan Python?


170

Apakah ada fungsi built-in yang berfungsi seperti zip()tetapi yang akan memberi pad hasil sehingga panjang daftar yang dihasilkan adalah panjang dari input terpanjang daripada input terpendek ?

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

Jawaban:


243

Di Python 3 Anda bisa menggunakan itertools.zip_longest

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

Anda dapat membuat pad dengan nilai yang berbeda daripada Nonedengan menggunakan fillvalueparameter:

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

Dengan Python 2 Anda bisa menggunakan itertools.izip_longest(Python 2.6+), atau Anda dapat menggunakan mapdengan None. Ini adalah sedikit diketahui fiturmap (tapi mapberubah dengan Python 3.x, jadi ini hanya bekerja dengan Python 2.x).

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

3
Apakah kita tidak memiliki solusi Python 3 non itertools?
PascalVKooten

3
@PascalvKooten tidak diperlukan. itertoolsadalah modul builtin C pula.
Antti Haapala

82

Untuk Python 2.6x gunakan itertoolsmodul izip_longest.

Untuk Python 3 gunakan zip_longestsebagai gantinya (tidak ada yang memimpin i).

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

8
Jika Anda ingin membuat kode Anda berdua python 2 dan python 3 kompatibel, Anda bisa menggunakannya six.moves.zip_longest.
Gamrix

5

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

2

solusi non 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

Saya menggunakan array 2d tetapi konsepnya mirip dengan menggunakan 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
Harap tambahkan penjelasan mengapa kode ini berfungsi. Atau mengapa itu adalah jawaban yang tepat
Aplikasi Suit Boy
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.