2009-08-14 39 views
104

有一個內置函數,它的工作原理是zip()但將墊的結果,這樣的結果列表的長度是最長投入,而非最短輸入的長度?Python:壓縮到最長的zip-like函數?

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

'itertools' ** **是一個內置的,即使一個模塊中。 – 2017-08-30 22:19:41

回答

137

您可以使用itertools.izip_longest(Python的2.6+),也可以使用mapNone。這是一個小知名的feature of map(但map在Python 3.x中更改,所以這隻適用於Python 2.x)。

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

@SilentGhost,我承認你的話,這在py3k中不起作用。我沒有py3k來確認。 – 2009-08-14 11:35:32

+1

'>>> list(map(None,a,b,c)) Traceback(last recent call last): 文件「」,第1行,在 list(map(None,a,b,c) )) TypeError:'NoneType'對象不可調用' – SilentGhost 2009-08-14 11:36:22

+0

您也可以參考文檔:http://docs.python.org/3.1/library/functions.html#map – SilentGhost 2009-08-14 11:37:10

74

對於Python 2.6倍,使用itertools模塊的izip_longest

對於Python 3,使用zip_longest代替(不是領先的i)。

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

如果你想讓你的代碼兼容python 2和python 3,你可以使用'six.moves.zip_longest'代替。 – Gamrix 2016-04-14 19:51:30

2

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