Python: ¿una función similar a una cremallera que se adapta a la longitud más larga?

¿Existe una función incorporada que funcione como zip() pero que rellene los resultados para que la longitud de la lista resultante sea la longitud de la entrada más larga en lugar de la más corta ?

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

En Python 3 puedes usar itertools.zip_longest

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

Puede rellenar con un valor diferente a None utilizando el parámetro fillvalue :

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

Con Python 2 puede usar itertools.izip_longest (Python 2.6+), o puede usar el map con None . Es una característica poco conocida del map (pero el map cambió en Python 3.x, por lo que solo funciona en Python 2.x).

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

Para Python itertools use el módulo izip_longest ‘s izip_longest .

Para Python 3 use zip_longest en zip_longest lugar (sin i ).

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

Solución no itertológica de 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) 

La solución de My Python 2 no incluye itertol:

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