Zip-Listen in Python

151

Ich versuche zu lernen, wie man Listen "zippt". Zu diesem Zweck habe ich ein Programm, in dem ich an einem bestimmten Punkt Folgendes mache:

x1, x2, x3 = stuff.calculations(withdataa)

Das gibt mir drei Listen, x1, x2, und x3, die jeweils sagen, Größe 20.

Jetzt mache ich:

zipall = zip(x1, x2, x3)

Wenn ich jedoch:

print "len of zipall %s" % len(zipall)

Ich bekomme 20, was ich nicht erwartet habe. Ich habe drei erwartet. Ich glaube, ich mache etwas grundlegend Falsches.

AJW
quelle
4
Was genau erwarten Sie zipzu tun? Warum sollten Sie drei Listen haben - wie würden sie aussehen?
Daniel Roseman
zip gibt eine Liste von Tupeln zurück.
Demo

Antworten:

225

Wenn Sie zip()drei Listen mit jeweils 20 Elementen zusammenfassen, enthält das Ergebnis zwanzig Elemente. Jedes Element ist ein Drei-Tupel.

Überzeugen Sie sich selbst:

In [1]: a = b = c = range(20)

In [2]: zip(a, b, c)
Out[2]: 
[(0, 0, 0),
 (1, 1, 1),
 ...
 (17, 17, 17),
 (18, 18, 18),
 (19, 19, 19)]

Um herauszufinden, wie viele Elemente jedes Tupel enthält, können Sie die Länge des ersten Elements untersuchen:

In [3]: result = zip(a, b, c)

In [4]: len(result[0])
Out[4]: 3

Dies funktioniert natürlich nicht, wenn die Listen zunächst leer waren.

NPE
quelle
1
len (Ergebnis [0]) funktioniert nicht. '
zip'
2
@GilbertS in Python 2 hat zipeine Liste zurückgegeben. In Python 3 ist es ein Iterator
Tomerikoo
63

zip nimmt eine Reihe von Listen Likes

a: a1 a2 a3 a4 a5 a6 a7...
b: b1 b2 b3 b4 b5 b6 b7...
c: c1 c2 c3 c4 c5 c6 c7...

und "zippt" sie in eine Liste, deren Einträge 3-Tupel sind (ai, bi, ci). Stellen Sie sich vor, Sie zeichnen einen Reißverschluss horizontal von links nach rechts.

Katriel
quelle
36

In Python 2.7 hat dies möglicherweise gut funktioniert:

>>> a = b = c = range(20)
>>> zip(a, b, c)

Aber in Python 3.4 sollte es so sein (andernfalls wird das Ergebnis ungefähr so ​​aussehen <zip object at 0x00000256124E7DC8>):

>>> a = b = c = range(20)
>>> list(zip(a, b, c))
Ajay
quelle
28

zip Erstellt eine neue Liste mit Tupeln, die Elemente aus den iterierbaren Argumenten enthalten:

>>> zip ([1,2],[3,4])
[(1,3), (2,4)]

Ich gehe davon aus, dass Sie versuchen, ein Tupel zu erstellen, in dem jedes Element eine Liste ist.

Geschichtenerzähler - Unslander Monica
quelle
14

Quelle: Mein Blog-Beitrag (bessere Formatierung)

Beispiel

numbers = [1,2,3]
letters = 'abcd'

zip(numbers, letters)
# [(1, 'a'), (2, 'b'), (3, 'c')]

Eingang

Null oder mehr Iterables [1] (z. B. Liste, Zeichenfolge, Tupel, Wörterbuch)

Ausgabe (Liste)

1. Tupel = (Element_1 der Zahlen, Element_1 der Buchstaben)

2. Tupel = (e_2 Zahlen, e_2 Buchstaben)

n-tes Tupel = (e_n Zahlen, e_n Buchstaben)

  1. Liste von n Tupeln: n ist die Länge des kürzesten Arguments (Eingabe)
    • len (Zahlen) == 3 <len (Buchstaben) == 4 → short = 3 → 3 Tupel zurückgeben
  2. Länge jedes Tupels = Anzahl der Argumente (Tupel nimmt ein Element von jedem Argument)
    • args = (Zahlen, Buchstaben); len (args) == 2 → Tupel mit 2 Elementen
  3. ith tuple = (element_i arg1, element_i arg2…, element_i arg n)

Randfälle

1) Leere Zeichenfolge: len (str) = 0 = keine Tupel

2) Einzelne Zeichenfolge: len (str) == 2 Tupel mit len ​​(args) == 1 Element (e)

zip()
# []
zip('')
# []
zip('hi')
# [('h',), ('i',)]

Zip in Aktion!

1. Erstellen Sie ein Wörterbuch [2] aus zwei Listen

keys = ["drink","band","food"]
values = ["La Croix", "Daft Punk", "Sushi"]

my_favorite = dict( zip(keys, values) )

my_favorite["drink"]
# 'La Croix'

my_faves = dict()
for i in range(len(keys)):
    my_faves[keys[i]] = values[i]
  • zip ist eine elegante, klare und prägnante Lösung

2. Drucken Sie Spalten in einer Tabelle

"*" [3] heißt "Auspacken": f(*[arg1,arg2,arg3]) == f(arg1, arg2, arg3)

student_grades = [
[   'Morty'  ,  1   ,  "B"  ],
[   'Rick'   ,  4   ,  "A"  ],
[   'Jerry'  ,  3   ,  "M"  ],
[  'Kramer'  ,  0   ,  "F"  ],
]

row_1 = student_grades[0]
print row_1
# ['Morty', 1, 'B']

columns = zip(*student_grades)
names = columns[0]
print names
# ('Morty', 'Rick', 'Jerry', 'Kramer')

Extra Credit: Entpacken

zip(*args) wird als "Entpacken" bezeichnet, da es den umgekehrten Effekt von hat zip

numbers = (1,2,3)
letters = ('a','b','c')

zipped = zip(numbers, letters)
print zipped
# [(1, 'a'), (2, 'b'), (3, 'c')]

unzipped = zip(*zipped)
print unzipped
# [(1, 2, 3), ('a', 'b', 'c')]
  • unzipped: tuple_1 = e1 jedes gezippten Tupels. tuple_2 = e2 von jedemzipped

Fußnoten

  1. Ein Objekt, das seine Mitglieder einzeln zurückgeben kann (z. B. Liste [1,2,3], Zeichenfolge 'Ich mag Codin', Tupel (1,2,3), Wörterbuch {'a': 1, 'b'). : 2})
  2. {Schlüssel1: Wert1, Schlüssel2: Wert2 ...}
  3. "Auspacken" (*)

* Code:

# foo - function, returns sum of two arguments
def foo(x,y):
    return x + y
print foo(3,4)
# 7

numbers = [1,2]
print foo(numbers)
# TypeError: foo() takes exactly 2 arguments (1 given)

print foo(*numbers)
# 3

*nahm numbers(1 arg) und "entpackte" seine '2 Elemente in 2 args

JBallin
quelle
14

Grundsätzlich funktioniert die Zip-Funktion in Listen mit Listen, Tupeln und Wörterbüchern. Wenn Sie IPython verwenden, geben Sie einfach zip ein. Und überprüfen Sie, worum es bei zip () geht.

Wenn Sie IPython nicht verwenden, installieren Sie es einfach: "pip install ipython"

Für Listen

a = ['a', 'b', 'c']
b = ['p', 'q', 'r']
zip(a, b)

Die Ausgabe ist [('a', 'p'), ('b', 'q'), ('c', 'r')

Für Wörterbuch:

c = {'gaurav':'waghs', 'nilesh':'kashid', 'ramesh':'sawant', 'anu':'raje'}
d = {'amit':'wagh', 'swapnil':'dalavi', 'anish':'mane', 'raghu':'rokda'}
zip(c, d)

Die Ausgabe ist:

[('gaurav', 'amit'),
 ('nilesh', 'swapnil'),
 ('ramesh', 'anish'),
 ('anu', 'raghu')]
Wagh
quelle
1
zip (c, d) führt zip durch (Liste (c), Liste (d))
Stephen Woodbridge
13

In Python 3 wird zip stattdessen ein Iterator zurückgegeben, der an eine Listenfunktion übergeben werden muss, um die komprimierten Tupel abzurufen:

x = [1, 2, 3]; y = ['a','b','c']
z = zip(x, y)
z = list(z)
print(z)
>>> [(1, 'a'), (2, 'b'), (3, 'c')]

Dann zu unzipihnen zurück konjugieren Sie einfach den gezippten Iterator:

x_back, y_back = zip(*z)
print(x_back); print(y_back)
>>> (1, 2, 3)
>>> ('a', 'b', 'c')

Wenn die ursprüngliche Form der Liste anstelle von Tupeln benötigt wird:

x_back, y_back = zip(*z)
print(list(x_back)); print(list(y_back))
>>> [1,2,3]
>>> ['a','b','c']
Shivid
quelle
1
Das Frage-Tag gibt Python 2.7 an. Dies ist für Python 3. Außerdem erwähnt diese Antwort dies bereits.
0 0
8

Der Vollständigkeit halber.

Wenn komprimierte Listenlängen nicht gleich sind. Die Länge der Ergebnisliste wird die kürzeste, ohne dass ein Fehler aufgetreten ist

>>> a = [1]
>>> b = ["2", 3]
>>> zip(a,b)
[(1, '2')]
transang
quelle
1

Ich glaube nicht, dass zipeine Liste zurückgegeben wird. zipgibt einen Generator zurück. Sie müssen tun list(zip(a, b)), um eine Liste von Tupeln zu erhalten.

x = [1, 2, 3]
y = [4, 5, 6]
zipped = zip(x, y)
list(zipped)
Ankur Kothari
quelle
1
Das Frage-Tag gibt Python 2.7 an. Dies ist für Python 3. Außerdem erwähnt diese Antwort dies bereits.
0 0
1

Es lohnt sich, hier hinzuzufügen, da es sich um eine so hochrangige Frage zu zip handelt. zipist großartiges, idiomatisches Python - aber es skaliert für große Listen überhaupt nicht sehr gut.

Anstatt:

books = ['AAAAAAA', 'BAAAAAAA', ... , 'ZZZZZZZ']
words = [345, 567, ... , 672]

for book, word in zip(books, words):
   print('{}: {}'.format(book, word))

Verwenden Sie izip. Für die moderne Verarbeitung speichert es es im L1-Cache-Speicher und ist für größere Listen weitaus leistungsfähiger. Verwenden Sie es so einfach wie das Hinzufügen eines i:

for book, word in izip(books, words):
   print('{}: {}'.format(book, word))
Micheal J. Roberts
quelle