2009-08-14 5 views
104

Y at-il une fonction intégrée qui fonctionne comme zip() mais ce pad volonté les résultats de telle sorte que la longueur de la liste résultante est la longueur de l'entrée la plus longue plutôt que la plus courte entrée?Python: fonction semblable à un zip qui permet d'obtenir des pads de la plus grande longueur?

>>> 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' ** est ** intégré, même si dans un module. –

Répondre

137

Vous pouvez utiliser itertools.izip_longest (Python 2.6+), ou vous pouvez utiliser map avec None. Il est un peu connu feature of map (mais map changé dans Python 3.x, donc cela ne fonctionne que dans Python 2.x).

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

@SilentGhost, j'ai pris votre parole que cela ne fonctionne pas dans py3k. Je n'ai pas py3k pour confirmer. –

+1

'>>> liste (carte (Aucune, a, b, c)) Traceback (dernier appel en dernier): Fichier" ", ligne 1, en liste (carte (aucun, a, b, c)) TypeError: L'objet 'NoneType' n'est pas appelable – SilentGhost

+0

vous pouvez également consulter les docs: http://docs.python.org/3.1/library/functions.html#map – SilentGhost

74

Pour utiliser Python 2.6x itertools du module de izip_longest.

Pour Python 3, utilisez zip_longest à la place (pas de i).

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

Si vous voulez que votre code soit compatible avec python 2 et python 3, vous pouvez utiliser 'six.moves.zip_longest' à la place. – Gamrix

2

non itertools Python 3 solution:

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) 
Questions connexes