Listy zip w Pythonie

151

Próbuję się nauczyć, jak „spakować” listy. W tym celu mam program, w którym w określonym momencie wykonuję następujące czynności:

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

To daje mi trzy list x1, x2i x3każdy z, powiedzmy, rozmiar 20.

Teraz ja robię:

zipall = zip(x1, x2, x3)

Jednak kiedy to robię:

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

Dostaję 20, co nie jest tym, czego się spodziewałem. Spodziewałem się trzech. Myślę, że robię coś zasadniczo złego.

AJW
źródło
4
Czego dokładnie spodziewasz zipsię zrobić? Dlaczego miałbyś mieć trzy listy - jak by one wyglądały?
Daniel Roseman
zip zwraca listę krotek.
Demo

Odpowiedzi:

225

Kiedy zip()połączysz trzy listy zawierające po 20 elementów każda, wynik będzie miał dwadzieścia elementów. Każdy element to trzy krotki.

Sam zobacz:

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

Aby dowiedzieć się, ile elementów zawiera każda krotka, możesz sprawdzić długość pierwszego elementu:

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

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

Oczywiście to nie zadziała, jeśli listy były puste na początku.

NPE
źródło
1
len (wynik [0]) nie zadziała. Obiekt „zip” nie jest indeksowany
GilbertS
2
@GilbertS w Pythonie 2 zipzwrócił listę. W Pythonie 3 jest to iterator
Tomerikoo
63

zip zajmuje kilka list polubień

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

i „pakuje” je do jednej listy, której wpisy składają się z trzech krotek (ai, bi, ci). Wyobraź sobie, że rysujesz zamek błyskawiczny poziomo od lewej do prawej.

Katriel
źródło
36

W Pythonie 2.7 mogło to działać dobrze:

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

Ale w Pythonie 3.4 powinno być (w przeciwnym razie wynik będzie mniej więcej taki <zip object at 0x00000256124E7DC8>):

>>> a = b = c = range(20)
>>> list(zip(a, b, c))
Ajay
źródło
28

zip tworzy nową listę, wypełnioną krotkami zawierającymi elementy z iterowalnych argumentów:

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

Spodziewam się, że spróbujesz utworzyć krotkę, w której każdy element jest listą.

StoryTeller - Unslander Monica
źródło
14

Źródło: Mój post na blogu (lepsze formatowanie)

Przykład

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

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

Wejście

Zero lub więcej iterable [1] (np. Lista, ciąg znaków, krotka, słownik)

Wyjście (lista)

Pierwsza krotka = (element_1 liczb, element_1 liter)

Druga krotka = (e_2 cyfry, e_2 litery)

n-ta krotka = (e_n liczb, e_n liter)

  1. Lista n krotek: n to długość najkrótszego argumentu (dane wejściowe)
    • len (liczby) == 3 <len (litery) == 4 → short = 3 → zwracają 3 krotki
  2. Długość każdej krotki = liczba argumentów (krotka pobiera element z każdego argumentu)
    • args = (cyfry, litery); len (args) == 2 → krotka z 2 elementami
  3. ith tuple = (element_i arg1, element_i arg2…, element_i arg n)

Przypadki krawędzi

1) Pusty ciąg: len (str) = 0 = brak krotek

2) Pojedynczy ciąg: len (str) == 2 krotki z len (args) == 1 element (y)

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

Zip w akcji!

1. Zbuduj słownik [2] z dwóch list

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 to eleganckie, przejrzyste i zwięzłe rozwiązanie

2. Wydrukuj kolumny w tabeli

„*” [3] nazywa się „rozpakowywaniem”: 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')

Dodatkowy kredyt: rozpakowanie

zip(*args) nazywa się „rozpakowywaniem”, ponieważ ma odwrotny skutek 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 każdej spakowanej krotki. tuple_2 = e2 każdegozipped

Przypisy

  1. Obiekt zdolny do zwracania swoich członków pojedynczo (np. Lista [1, 2, 3], łańcuch „I like codin”, tuple (1, 2, 3), słownik {„a”: 1, „b” : 2})
  2. {klucz1: wartość1, klucz2: wartość2 ...}
  3. „Rozpakowanie” (*)

* Kod:

# 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

*wziął numbers(1 argument) i „rozpakował” jego '2 elementy na 2 argumenty

JBallin
źródło
14

Zasadniczo funkcja zip działa na listach, krotkach i słownikach w Pythonie. Jeśli używasz IPython, po prostu wpisz zip? I sprawdź, o co chodzi w zip ().

Jeśli nie używasz IPythona, po prostu go zainstaluj: "pip install ipython"

Do list

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

Wynik jest [('a', 'p'), ('b', 'q'), ('c', 'r')

Do słownika:

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

Wynik to:

[('gaurav', 'amit'),
 ('nilesh', 'swapnil'),
 ('ramesh', 'anish'),
 ('anu', 'raghu')]
Wagh
źródło
1
zip (c, d) wykonuje zip (list (c), list (d))
Stephen Woodbridge
13

W Pythonie 3 zip zamiast tego zwraca iterator i musi zostać przekazany do funkcji listy, aby uzyskać spakowane krotki:

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

Następnie do unzipnich z powrotem po prostu skoniuguj spakowany iterator:

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

Jeśli zamiast krotek potrzebna jest oryginalna lista:

x_back, y_back = zip(*z)
print(list(x_back)); print(list(y_back))
>>> [1,2,3]
>>> ['a','b','c']
Żywe
źródło
1
Znacznik pytania informuje o Pythonie 2.7; to jest dla Pythona 3. Poza tym ta odpowiedź już o tym wspomina.
0 0
8

Ze względu na kompletność.

Gdy długości list spakowanych nie są równe. Lista wyników stanie się najkrótszą, bez żadnego błędu

>>> a = [1]
>>> b = ["2", 3]
>>> zip(a,b)
[(1, '2')]
transang
źródło
1

Myślę, że nie zipzwraca listy. zipzwraca generator. Musisz zrobić, list(zip(a, b))aby uzyskać listę krotek.

x = [1, 2, 3]
y = [4, 5, 6]
zipped = zip(x, y)
list(zipped)
Ankur Kothari
źródło
1
Znacznik pytania informuje o Pythonie 2.7; to jest dla Pythona 3. Poza tym ta odpowiedź już o tym wspomina.
0 0
1

Warto tutaj dodać, ponieważ jest to tak wysoko rankingowe pytanie na zip. zipjest świetny, idiomatyczny Python - ale nie skaluje się zbyt dobrze w przypadku dużych list.

Zamiast:

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

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

Użyj izip. W przypadku nowoczesnego przetwarzania przechowuje go w pamięci podręcznej L1 i jest znacznie bardziej wydajny w przypadku większych list. Używaj go tak po prostu, jak dodając i:

for book, word in izip(books, words):
   print('{}: {}'.format(book, word))
Micheal J. Roberts
źródło