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.


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.


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.



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

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.


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


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

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

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

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)

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))
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.