Wie konvertiere ich eine Liste von Tupeln in mehrere Listen?


105

Angenommen, ich habe eine Liste mit Tupeln und möchte in mehrere Listen konvertieren.

Zum Beispiel ist die Liste der Tupel

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

Gibt es eine integrierte Funktion in Python, die es konvertiert in:

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

Dies kann ein einfaches Programm sein. Aber ich bin nur neugierig auf die Existenz einer solchen integrierten Funktion in Python.

Antworten:


159

Die eingebaute Funktion macht zip()fast das, was Sie wollen:

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

Der einzige Unterschied besteht darin, dass Sie Tupel anstelle von Listen erhalten. Sie können sie mit in Listen konvertieren

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

40

Aus den Python-Dokumenten :

Mit zip () kann in Verbindung mit dem Operator * eine Liste entpackt werden:

Spezifisches Beispiel:

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

Oder wenn Sie wirklich Listen wollen:

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


4

franklsf95 strebt in seiner Antwort nach Leistung und entscheidet sich für list.append(), aber sie sind nicht optimal.

Beim Hinzufügen von Listenverständnissen kam ich zu folgendem Ergebnis:

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)}')

Dies ergab das Ergebnis:

zip:            122.11585397789766
append:         356.44876132614047
list comp:      144.637765085659

Wenn Sie also nach der Aufführung sind, sollten Sie wahrscheinlich verwenden, zip()obwohl das Listenverständnis nicht zu weit zurückliegt. Die Leistung von appendist im Vergleich eigentlich ziemlich schlecht.


1

Obwohl *zipder folgende Code pythonischer ist, bietet er eine viel bessere Leistung:

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

Auch wenn die ursprüngliche Liste zsleer ist, *zipwird ausgelöst, aber dieser Code kann richtig verarbeiten.

Ich habe gerade ein kurzes Experiment durchgeführt und hier ist das Ergebnis:

Using *zip:     1.54701614s
Using append:   0.52687597s

Mehrfaches Ausführen appendist 3x - 4x schneller als zip! Das Testskript ist hier:

#!/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))

Meine Python-Version:

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.

1

Zusätzlich zu Claudius Antwort können Sie Folgendes verwenden:

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

Bearbeitet nach @Peyman mohseni kiasari


1
Nein! es wird dir geben (1, 3, 5)und (2, 4, 6)keine Listen. Sie sollten verwendenmap(list, zip(*[(1, 2), (3, 4), (5, 6)]))
Peyman

0

Wenn Sie die Antwort von Claudiu und Claudiu ergänzen und die Karte aus den itertools in Python 3 importiert werden muss, verwenden Sie auch ein Listenverständnis wie:

[[*x] for x in zip(*[(1,2),(3,4),(5,6)])]
>>> [[1, 3, 5], [2, 4, 6]]
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.