web-dev-qa-db-fra.com

Python: fonction de type zip qui compresse au maximum?

Existe-t-il une fonction intégrée qui fonctionne comme Zip() mais qui compilera les résultats de sorte que la longueur de la liste résultante soit la longueur de l'entrée la plus longue plutôt que de la valeur - le plus court entrée?

>>> 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)]
138
Mark Harrison

Dans Python 3, vous pouvez utiliser itertools.Zip_longest

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

Vous pouvez utiliser une valeur différente de None à l'aide du paramètre fillvalue:

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

Avec Python 2, vous pouvez utiliser itertools.izip_longest (Python 2.6+), ou vous pouvez utiliser map avec None. C'est un peu connu fonctionnalité de map (mais map a changé dans Python 3.x, de sorte que cela ne fonctionne que dans = Python 2.x).

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

Pour Python 2.6x, utilisez itertools le module izip_longest .

Pour Python 3 utilisez Zip_longest à la place (pas de i au début).

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

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)
3
dansalmo

non itertools Ma solution Python 2:

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