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.
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.
Vous avez presque eu la réponse vous-même. N'utilisez pas map
au lieu de Zip
. Utilisez map
ETZip
.
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.
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
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]]
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.
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()
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]]