Wie füge ich Listen zu einer Liste von Tupeln zusammen?


298

Was ist der pythonische Ansatz, um Folgendes zu erreichen?

# Original lists:

list_a = [1, 2, 3, 4]
list_b = [5, 6, 7, 8]

# List of tuples from 'list_a' and 'list_b':

list_c = [(1,5), (2,6), (3,7), (4,8)]

Jedes Mitglied von list_cist ein Tupel, dessen erstes Mitglied von list_aund das zweite von stammt list_b.

Antworten:


443

In Python 2:

>>> list_a = [1, 2, 3, 4]
>>> list_b = [5, 6, 7, 8]
>>> zip(list_a, list_b)
[(1, 5), (2, 6), (3, 7), (4, 8)]

In Python 3:

>>> list_a = [1, 2, 3, 4]
>>> list_b = [5, 6, 7, 8]
>>> list(zip(list_a, list_b))
[(1, 5), (2, 6), (3, 7), (4, 8)]

77
Sie müssen wissen, dass die Zip-Funktion am Ende der kürzesten Liste stoppt, was möglicherweise nicht immer das ist, was Sie wollen. Das itertoolsModul definiert eine zip_longest()Methode, die am Ende der längsten Liste endet und fehlende Werte mit etwas füllt, das Sie als Parameter angeben.
Adrien Plisson

5
@Adrien: Prost auf deinen zutreffenden Kommentar. Für Python 2.x , s/zip_longest()/izip_longest(). In Python 3.x umbenannt in zip_longest().
mechanisches

könnte ich [(1,5), (1,6), (1,7), (1,8), (2,5), (2,6) usw. mit dem Befehl zip erstellen?
Mona Jalal

3
@MonaJalal: Nein, das ist kein Pairing, das schafft das Produkt der Listen. itertools.product()tut das.
Martijn Pieters

2
Beachten Sie, dass zip zumindest in python3.6 keine Liste zurückgibt. Sie benötigen also stattdessen eine Liste (zip (list_a, list_b))
Supamee

141

In Python 3.0 gibt zip ein zip-Objekt zurück. Sie können eine Liste daraus erstellen, indem Sie anrufen list(zip(a, b)).


3
Dies mag trivial sein, aber seien Sie gewarnt, dass Sie durch die direkte Verwendung in einer for-Schleife einen Generator erhalten, der nach einmaliger Verwendung erschöpft ist. Speichern Sie in einer Variablen, wenn Sie es öfter verwenden
möchten

13

Sie können Karte Lambda verwenden

a = [2,3,4]
b = [5,6,7]
c = map(lambda x,y:(x,y),a,b)

Dies funktioniert auch, wenn die Länge der ursprünglichen Listen nicht übereinstimmt


1
Warum ein Lambda verwenden? map(None, a,b)
Padraic Cunningham

Ich habe nur Zugriff auf Python 3.5.
Dark Knight

3
Wenn Sie Python3 verwenden würden, wäre c keine Liste, sondern ein Kartenobjekt. Auch die Verwendung eines Lambda ist viel weniger effizient als nur das Zippen. Wenn Sie Listen unterschiedlicher Länge haben und damit umgehen möchten, würden Sie es verwenden izip_longest / zip_longest
Padraic Cunningham


6

Ich bin nicht sicher, ob dies eine pythonische Art ist oder nicht, aber dies scheint einfach zu sein, wenn beide Listen die gleiche Anzahl von Elementen haben:

list_a = [1, 2, 3, 4]

list_b = [5, 6, 7, 8]

list_c=[(list_a[i],list_b[i]) for i in range(0,len(list_a))]

5

Ich weiß, dass dies eine alte Frage ist und bereits beantwortet wurde, aber aus irgendeinem Grund möchte ich diese alternative Lösung trotzdem veröffentlichen. Ich weiß, es ist einfach herauszufinden, welche eingebaute Funktion die "Magie" bewirkt, die Sie benötigen, aber es tut nicht weh zu wissen, dass Sie es selbst tun können.

>>> list_1 = ['Ace', 'King']
>>> list_2 = ['Spades', 'Clubs', 'Diamonds']
>>> deck = []
>>> for i in range(max((len(list_1),len(list_2)))):
        while True:
            try:
                card = (list_1[i],list_2[i])
            except IndexError:
                if len(list_1)>len(list_2):
                    list_2.append('')
                    card = (list_1[i],list_2[i])
                elif len(list_1)<len(list_2):
                    list_1.append('')
                    card = (list_1[i], list_2[i])
                continue
            deck.append(card)
            break
>>>
>>> #and the result should be:
>>> print deck
>>> [('Ace', 'Spades'), ('King', 'Clubs'), ('', 'Diamonds')]

2
Das Ändern einer der Eingabelisten (wenn sie sich in der Länge unterscheiden) ist kein netter Nebeneffekt. Auch die beiden Zuordnungen zu cardin if-elifwerden nicht benötigt, deshalb haben Sie die continue. (In der Tat, ohne die continuemüssten Sie die Listen nicht ändern: Beide zuvor genannten Aufgaben sollten dann beibehalten werden card = (list_1[i], '')und werden card = ('', list_2[1])jeweils.)
ᴠɪɴᴄᴇɴᴛ

5

Die Ausgabe, die Sie in der Problemstellung angezeigt haben, ist nicht das Tupel, sondern die Liste

list_c = [(1,5), (2,6), (3,7), (4,8)]

prüfen Auf

type(list_c)

Wenn Sie möchten, dass das Ergebnis als Tupel aus list_a und list_b angezeigt wird, tun Sie dies

tuple(zip(list_a,list_b)) 

Aus meiner Sicht scheint es das zu sein, wonach ich suche und für beide (Liste und Tupel) gut zu funktionieren. Denn wenn Sie print verwenden , sehen Sie den richtigen Wert (wie erwartet und von @cyborg und @Lodewijk erwähnt) und nichts, was mit dem Objekt zu tun hat, wie: <map object at 0x000001F266DCE5C0>oder <zip object at 0x000002629D204C88>. Zumindest scheint die Lösung für Karte und Zip (allein) für mich unvollständig (oder zu kompliziert) zu sein.
Wagner_SOFC

1
Die Frage besagt, dass sie eine Liste von Tupeln wollen, kein Tupel von Tupeln.
Goryh

1

Eine Alternative ohne Verwendung zip:

list_c = [(p1, p2) for idx1, p1 in enumerate(list_a) for idx2, p2 in enumerate(list_b) if idx1==idx2]

Falls man nicht nur Tupel 1. mit 1., 2. mit 2. bekommen möchte ... sondern alle möglichen Kombinationen der 2 Listen, wäre das erledigt

list_d = [(p1, p2) for p1 in list_a for p2 in list_b]
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.