web-dev-qa-db-fra.com

Zip avec sortie liste au lieu de tuple

Quel est le moyen le plus rapide et le plus élégant de créer une liste à partir de deux listes?

J'ai

In [1]: a=[1,2,3,4,5,6]

In [2]: b=[7,8,9,10,11,12]

In [3]: Zip(a,b)
Out[3]: [(1, 7), (2, 8), (3, 9), (4, 10), (5, 11), (6, 12)]

Et j'aimerais avoir

In [3]: some_method(a,b)
Out[3]: [[1, 7], [2, 8], [3, 9], [4, 10], [5, 11], [6, 12]]

Je pensais utiliser map au lieu de Zip, mais je ne sais pas s'il existe une méthode de bibliothèque standard à utiliser comme premier argument.

Je peux définir ma propre fonction pour cela, et utiliser map, ma question est de savoir si quelque chose a déjà été implémenté. Non est aussi une réponse.

53
Jan Vorcak

Si vous zippez plus de 2 listes (ou même seulement 2, d'ailleurs), une manière lisible serait:

[list(a) for a in Zip([1,2,3], [4,5,6], [7,8,9])]

Ceci utilise les compréhensions de liste et convertit chaque élément de la liste (tuples) en listes.

59
D K

Vous avez presque eu la réponse vous-même. N'utilisez pas map au lieu de Zip. Utilisez mapETZip.

Vous pouvez utiliser map avec Zip pour une approche élégante et fonctionnelle:

list(map(list, Zip(a, b)))

Zip renvoie une liste de n-uplets. map(list, [...]) appelle list sur chaque tuple de la liste. list(map([...]) transforme l'objet de la carte en une liste lisible.

27
Eldamir

J'aime l'élégance de la fonction Zip, mais utiliser la fonction itemgetter () dans le module opérateur semble être beaucoup plus rapide. J'ai écrit un script simple pour tester ceci:

import time
from operator import itemgetter

list1 = list()
list2 = list()
origlist = list()
for i in range (1,5000000):
        t = (i, 2*i)
        origlist.append(t)

print "Using Zip"
starttime = time.time()
list1, list2 = map(list, Zip(*origlist))
elapsed = time.time()-starttime
print elapsed

print "Using itemgetter"
starttime = time.time()
list1 = map(itemgetter(0),origlist)
list2 = map(itemgetter(1),origlist)
elapsed = time.time()-starttime
print elapsed

Je m'attendais à ce que Zip soit plus rapide, mais la méthode itemgetter l'emporte de loin:

Using Zip
6.1550450325
Using itemgetter
0.768098831177
13
kslnet

Que dis-tu de ça?

>>> def list_(*args): return list(args)

>>> map(list_, range(5), range(9,4,-1))
[[0, 9], [1, 8], [2, 7], [3, 6], [4, 5]]

Ou même mieux:

>>> def Zip_(*args): return map(list_, *args)
>>> Zip_(range(5), range(9,4,-1))
[[0, 9], [1, 8], [2, 7], [3, 6], [4, 5]]
3
Broseph

En général, je n'aime pas utiliser lambda, mais ...

>>> a = [1, 2, 3, 4, 5]
>>> b = [6, 7, 8, 9, 10]
>>> c = lambda a, b: [list(c) for c in Zip(a, b)]
>>> c(a, b)
[[1, 6], [2, 7], [3, 8], [4, 9], [5, 10]]

Si vous avez besoin de plus de vitesse, la carte est légèrement plus rapide:

>>> d = lambda a, b: map(list, Zip(a, b))
>>> d(a, b)
[[1, 6], [2, 7], [3, 8], [4, 9], [5, 10]]

Cependant, map est considéré comme non rythmique et ne doit être utilisé que pour le réglage des performances.

3
Ceasar Bautista

Utiliser numpy

La définition de l'élégance peut être assez discutable, mais si vous travaillez avec numpy, la création d'un tableau et sa conversion en liste (si nécessaire ...) pourraient s'avérer très pratiques même s'ils ne sont pas aussi efficaces que l'utilisation de la fonction map ou de la compréhension de la liste .

import numpy as np 
a = b = range(10)
zipped = Zip(a,b)
result = np.array(zipped).tolist()
Out: [[0, 0],
 [1, 1],
 [2, 2],
 [3, 3],
 [4, 4],
 [5, 5],
 [6, 6],
 [7, 7],
 [8, 8],
 [9, 9]]

Sinon, vous pouvez utiliser directement la fonction Zip/ np.dstack :

np.dstack((a,b))[0].tolist()
0
G M

La compréhension de la liste serait une solution très simple, je suppose.

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

b=[7,8,9,10,11,12]

x = [[i, j] for i, j in Zip(a,b)]

print(x)

output : [[1, 7], [2, 8], [3, 9], [4, 10], [5, 11], [6, 12]]
0
axai_m