it-swarm.com.de

Zip mit Listenausgabe statt Tupel

Was ist der schnellste und eleganteste Weg, Listenlisten aus zwei Listen zu erstellen?

Ich habe

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

Und ich hätte gerne

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

Ich habe über die Verwendung von map anstelle von zip nachgedacht, aber ich weiß nicht, ob es eine Standardbibliothek gibt, die als erstes Argument verwendet werden kann.

Ich kann meine eigene Funktion dafür definieren und map verwenden, meine Frage ist, ob da schon etwas implementiert ist. Nein ist auch eine Antwort.

53
Jan Vorcak

Wenn Sie mehr als 2 Listen (oder auch nur 2) zusammenfassen, können Sie folgendermaßen lesen:

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

Dabei werden Listenverständnisse verwendet und jedes Element in der Liste (Tupel) in Listen umgewandelt.

59
D K

Sie hätten fast die Antwort selbst gehabt. Verwenden Sie nicht map anstelle von Zip. Verwenden Sie mapUNDZip.

Sie können map zusammen mit Zip für einen eleganten, funktionalen Ansatz verwenden:

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

Zip gibt eine Liste von Tupeln zurück. map(list, [...]) ruft list für jedes Tuple in der Liste auf. list(map([...]) macht das Kartenobjekt in eine lesbare Liste.

27
Eldamir

Ich liebe die Eleganz der Zip-Funktion, aber die Verwendung der itemgetter () - Funktion im Operator-Modul scheint viel schneller zu sein. Ich habe ein einfaches Skript geschrieben, um dies zu testen:

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

Ich habe erwartet, dass Zip schneller sein wird, aber die itemgetter-Methode gewinnt mit Abstand.

Using Zip
6.1550450325
Using itemgetter
0.768098831177
13
kslnet

Wie wäre es damit?

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

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

Oder noch besser:

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

Generell mag ich kein Lambda, aber ...

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

Wenn Sie die zusätzliche Geschwindigkeit benötigen, ist die Karte etwas schneller:

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

Die Karte wird jedoch als unpythonic betrachtet und sollte nur zur Leistungsoptimierung verwendet werden.

3
Ceasar Bautista

Mit numpy

Die Definition von Eleganz kann durchaus fragwürdig sein, aber wenn Sie mit numpy arbeiten, kann die Erstellung eines Arrays und die Umwandlung in eine Liste (falls erforderlich ...) sehr praktisch sein, auch wenn sie im Vergleich zur map-Funktion oder zum Listenverständnis nicht so effizient ist .

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

Ansonsten können Sie die Zip-Funktion überspringen, die Sie direkt verwenden können np.dstack :

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

Listenverständnis wäre eine sehr einfache Lösung, denke ich.

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