Daftar zip dengan Python

151

Saya mencoba mempelajari cara "zip" daftar. Untuk tujuan ini, saya memiliki program, di mana pada titik tertentu, saya melakukan hal berikut:

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

Ini memberi saya tiga daftar, x1, x2, dan x3, masing-masing, mengatakan, ukuran 20.

Sekarang saya lakukan:

zipall = zip(x1, x2, x3)

Namun, ketika saya melakukannya:

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

Saya mendapatkan 20, yang bukan itu yang saya harapkan. Saya mengharapkan tiga. Saya pikir saya melakukan sesuatu yang secara fundamental salah.

AJW
sumber
4
Apa yang sebenarnya Anda harapkan zipuntuk dilakukan? Mengapa Anda harus memiliki tiga daftar - seperti apa bentuknya?
Daniel Roseman
zip mengembalikan daftar tupel.
Demo

Jawaban:

225

Ketika Anda zip()bersama-sama tiga daftar yang masing-masing berisi 20 elemen, hasilnya memiliki dua puluh elemen. Setiap elemen adalah tiga tupel.

Lihat diri mu sendiri:

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

Untuk mengetahui berapa banyak elemen yang berisi masing-masing tuple, Anda dapat memeriksa panjang elemen pertama:

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

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

Tentu saja, ini tidak akan berfungsi jika daftar kosong untuk memulai.

NPE
sumber
1
len (hasil [0]) tidak akan berfungsi. objek 'zip' tidak dapat
disubkripsikan
2
@GilbertS di Python 2 zipmengembalikan daftar. Dalam Python 3 itu adalah iterator
Tomerikoo
63

zip membutuhkan banyak daftar suka

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

dan "ritsleting" mereka ke dalam satu daftar yang isinya 3-tupel (ai, bi, ci). Bayangkan menggambar ritsleting secara horizontal dari kiri ke kanan.

Katriel
sumber
36

Dalam Python 2.7 ini mungkin berhasil:

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

Tetapi dalam Python 3.4 seharusnya (jika tidak, hasilnya akan menjadi seperti <zip object at 0x00000256124E7DC8>):

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

zip membuat daftar baru, diisi dengan tuple yang mengandung elemen dari argumen iterable:

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

Saya berharap apa yang Anda coba adalah membuat tuple di mana setiap elemen adalah daftar.

StoryTeller - Unslander Monica
sumber
14

Sumber: My Blog Post (pemformatan yang lebih baik)

Contoh

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

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

Memasukkan

Nol atau lebih iterables [1] (mis. Daftar, string, tuple, kamus)

Output (daftar)

1 tuple = (elemen_1 angka, elemen_1 huruf)

Tuple 2 = (angka e_2, e_2 huruf)

...

n-th tuple = (angka e_n, huruf e_n)

  1. Daftar n tupel: n adalah panjang argumen terpendek (input)
    • len (angka) == 3 <len (huruf) == 4 → pendek = 3 → kembalikan 3 tupel
  2. Panjang setiap tuple = # dari args (tuple mengambil elemen dari setiap arg)
    • args = (angka, huruf); len (args) == 2 → tuple dengan 2 elemen
  3. ituple = (element_i arg1, element_i arg2 ..., element_i arg n)

Kasus Tepi

1) String Kosong: len (str) = 0 = tidak ada tupel

2) Single String: len (str) == 2 tuple dengan len (args) == 1 elemen

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

Zip in Action!

1. Buat kamus [2] dari dua daftar

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 adalah solusi yang elegan, jelas, & ringkas

2. Cetak kolom dalam tabel

"*" [3] disebut "membongkar": 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')

Kredit Ekstra: Membuka Ritsleting

zip(*args) disebut "unzipping" karena memiliki efek kebalikan dari 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 dari setiap tuple yang di-zip. tuple_2 = e2 masing-masingzipped

Catatan kaki

  1. Objek yang mampu mengembalikan anggotanya satu per satu (mis. Daftar [1,2,3], string 'I like codin', tuple (1,2,3), kamus {'a': 1, 'b' : 2})
  2. {key1: value1, key2: value2 ...}
  3. “Bongkar” (*)

* Kode:

# 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

*mengambil numbers(1 arg) dan "membongkar" nya 'elemen 2 menjadi 2 args

JBallin
sumber
14

Pada dasarnya fungsi zip berfungsi pada daftar, tupel dan kamus dengan Python. Jika Anda menggunakan IPython maka cukup ketik zip? Dan periksa apa zip ().

Jika Anda tidak menggunakan IPython maka cukup instal: "pip install ipython"

Untuk daftar

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

Outputnya adalah [('a', 'p'), ('b', 'q'), ('c', 'r')

Untuk kamus:

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

Outputnya adalah:

[('gaurav', 'amit'),
 ('nilesh', 'swapnil'),
 ('ramesh', 'anish'),
 ('anu', 'raghu')]
Wagh
sumber
1
zip (c, d) sedang melakukan zip (daftar (c), daftar (d))
Stephen Woodbridge
13

Dalam Python 3 zip mengembalikan iterator dan perlu diteruskan ke fungsi daftar untuk mendapatkan zip tuple:

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

Kemudian untuk unzipmereka kembali hanya konjugasi iterator zip:

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

Jika bentuk asli daftar diperlukan, bukan tupel:

x_back, y_back = zip(*z)
print(list(x_back)); print(list(y_back))
>>> [1,2,3]
>>> ['a','b','c']
Terpisah
sumber
1
Tag pertanyaan menyatakan Python 2.7; ini untuk Python 3. Selain itu, jawaban ini sudah menyebutkan ini.
0 0
8

Demi kelengkapan itu.

Ketika panjang daftar zip tidak sama. Panjang daftar hasil akan menjadi yang terpendek tanpa terjadi kesalahan

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

Saya tidak berpikir zipmengembalikan daftar. zipmengembalikan generator. Yang harus Anda lakukan list(zip(a, b))untuk mendapatkan daftar tupel.

x = [1, 2, 3]
y = [4, 5, 6]
zipped = zip(x, y)
list(zipped)
Ankur Kothari
sumber
1
Tag pertanyaan menyatakan Python 2.7; ini untuk Python 3. Selain itu, jawaban ini sudah menyebutkan ini.
0 0
1

Layak untuk ditambahkan di sini karena ini adalah pertanyaan dengan peringkat sangat tinggi di zip. zipitu hebat, idiom Python - tetapi itu tidak skala sama sekali untuk daftar besar.

Dari pada:

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

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

Gunakan izip. Untuk pemrosesan modern, ia menyimpannya dalam memori L1 Cache dan jauh lebih berkinerja untuk daftar yang lebih besar. Gunakan itu hanya dengan menambahkan i:

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