146 votes

Comment convertir une liste de tuples en listes multiples ?

Supposons que j'ai une liste de tuples et que je veux la convertir en listes multiples.

Par exemple, la liste des tuples est

[(1,2),(3,4),(5,6),]

Existe-t-il une fonction intégrée dans Python qui le convertit en :

[1,3,5],[2,4,6]

Il peut s'agir d'un programme simple. Mais je suis juste curieux de savoir s'il existe une telle fonction intégrée dans Python.

212voto

Sven Marnach Points 133943

La fonction intégrée zip() fera presque ce que vous voulez :

>>> list(zip(*[(1, 2), (3, 4), (5, 6)]))
[(1, 3, 5), (2, 4, 6)]

La seule différence est que vous obtenez des tuples au lieu de listes. Vous pouvez les convertir en listes en utilisant

list(map(list, zip(*[(1, 2), (3, 4), (5, 6)])))

0 votes

En Python, vous devez convertir l'itérateur résultant en une liste pour voir le contenu : list(zip(*[(1, 2), (3, 4), (5, 6)])) .

1 votes

@MERose Cette réponse a été écrite pour Python 2. À l'époque zip() et map() retournent des listes, et non des itérateurs paresseux, comme c'est le cas dans Python 3. Je vais mettre à jour la réponse.

0 votes

Je sais, je sais. Mon commentaire avait pour but d'éviter toute confusion dans le public d'aujourd'hui. De plus, j'ai oublié d'écrire "Python 3".

51voto

Claudiu Points 58398

De la documentation python :

zip() en conjonction avec l'opérateur * peut être utilisé pour dézipper une liste :

Exemple concret :

>>> zip((1,3,5),(2,4,6))
[(1, 2), (3, 4), (5, 6)]
>>> zip(*[(1, 2), (3, 4), (5, 6)])
[(1, 3, 5), (2, 4, 6)]

Ou, si vous voulez vraiment des listes :

>>> map(list, zip(*[(1, 2), (3, 4), (5, 6)]))
[[1, 3, 5], [2, 4, 6]]

9voto

Artsiom Rudzenka Points 9771

Utilisez :

a = [(1,2),(3,4),(5,6),]    
b = zip(*a)
>>> [(1, 3, 5), (2, 4, 6)]

6voto

Baldrickk Points 2699

Franklsf95 mise sur la performance dans sa réponse et opte pour list.append() mais ils ne sont pas optimaux.

En ajoutant des compréhensions de listes, j'ai obtenu ce qui suit :

def t1(zs):
    xs, ys = zip(*zs)
    return xs, ys

def t2(zs):
    xs, ys = [], []
    for x, y in zs:
        xs.append(x)
        ys.append(y)
    return xs, ys

def t3(zs):
    xs, ys = [x for x, y in zs], [y for x, y in zs]
    return xs, ys

if __name__ == '__main__':
    from timeit import timeit
    setup_string='''\
N = 2000000
xs = list(range(1, N))
ys = list(range(N+1, N*2))
zs = list(zip(xs, ys))
from __main__ import t1, t2, t3
'''
    print(f'zip:\t\t{timeit('t1(zs)', setup=setup_string, number=1000)}')
    print(f'append:\t\t{timeit('t2(zs)', setup=setup_string, number=1000)}')
    print(f'list comp:\t{timeit('t3(zs)', setup=setup_string, number=1000)}')

Cela a donné le résultat :

zip:            122.11585397789766
append:         356.44876132614047
list comp:      144.637765085659

Donc si vous recherchez la performance, vous devriez probablement utiliser zip() bien que les compréhensions de listes ne soient pas trop loin derrière. Les performances de append est en fait assez pauvre en comparaison.

5voto

franklsf95 Points 909

Malgré *zip étant plus Pythonique, le code suivant a de bien meilleures performances :

xs, ys = [], []
for x, y in zs:
    xs.append(x)
    ys.append(y)

De plus, lorsque la liste originale zs est vide, *zip sera soulevé, mais ce code peut gérer correctement.

Je viens de faire une expérience rapide, et voici le résultat :

Using *zip:     1.54701614s
Using append:   0.52687597s

Je l'ai fait tourner plusieurs fois, append est 3x - 4x plus rapide que zip ! Le test script est ici :

#!/usr/bin/env python3
import time

N = 2000000
xs = list(range(1, N))
ys = list(range(N+1, N*2))
zs = list(zip(xs, ys))

t1 = time.time()

xs_, ys_ = zip(*zs)
print(len(xs_), len(ys_))

t2 = time.time()

xs_, ys_ = [], []
for x, y in zs:
    xs_.append(x)
    ys_.append(y)
print(len(xs_), len(ys_))

t3 = time.time()

print('Using *zip:\t{:.8f}s'.format(t2 - t1))
print('Using append:\t{:.8f}s'.format(t3 - t2))

Ma version Python :

Python 3.6.3 (default, Oct 24 2017, 12:18:40)
[GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.42)] on darwin
Type "help", "copyright", "credits" or "license" for more information.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X