รายการ Zip ใน Python


151

ฉันพยายามที่จะเรียนรู้วิธีการ "ซิป" รายการ ด้วยเหตุนี้ฉันมีโปรแกรมซึ่ง ณ จุดใดจุดหนึ่งฉันทำต่อไปนี้:

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

นี้จะช่วยให้เราสามรายการx1, x2และx3แต่ละของการพูดขนาด 20

ตอนนี้ฉันทำ:

zipall = zip(x1, x2, x3)

อย่างไรก็ตามเมื่อฉัน:

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

ฉันได้ 20 ซึ่งไม่ใช่สิ่งที่ฉันคาดไว้ ฉันคาดหวังสาม ฉันคิดว่าฉันกำลังทำบางสิ่งผิดปกติ


4
คุณคาดหวังว่าzipจะทำอะไรกันแน่? ทำไมคุณควรมีสามรายการ - พวกเขาจะมีลักษณะอย่างไร
Daniel Roseman

zip ส่งคืนรายการ tuples
สาธิต

คำตอบ:


225

เมื่อคุณzip()รวมสามรายการที่ประกอบด้วย 20 องค์ประกอบแต่ละผลลัพธ์จะมีองค์ประกอบยี่สิบรายการ แต่ละองค์ประกอบเป็นสาม tuple

ดูตัวเอง:

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

หากต้องการทราบว่าแต่ละองค์ประกอบมี tuple กี่ตัวคุณสามารถตรวจสอบความยาวขององค์ประกอบแรก:

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

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

แน่นอนว่าจะไม่ทำงานหากรายการว่างเปล่าที่จะเริ่มต้นด้วย


1
len (ผลลัพธ์ [0]) ไม่ทำงาน วัตถุ 'zip' ไม่สามารถ
ถอดได้

2
@GilbertS ใน Python 2 zipส่งคืนรายการ ใน Python 3 มันเป็นตัววนซ้ำ
Tomerikoo

63

zip ชอบรายการจำนวนมาก

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

และ "ซิป" พวกเขาเป็นหนึ่งรายการที่มีรายการเป็น (ai, bi, ci)3 ลองนึกภาพการวาดซิปแนวนอนจากซ้ายไปขวา



36

ใน Python 2.7 สิ่งนี้อาจใช้ได้ดี:

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

แต่ใน Python 3.4 ควรเป็นอย่างอื่น (ผลลัพธ์จะออกมาเหมือน<zip object at 0x00000256124E7DC8>):

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

28

zip สร้างรายการใหม่ที่เต็มไปด้วย tuples ที่มีองค์ประกอบจากข้อโต้แย้ง iterable:

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

ฉันคาดหวังสิ่งที่คุณพยายามทำคือสร้างสิ่งอันดับที่แต่ละองค์ประกอบเป็นรายการ


14

ที่มา: โพสต์บล็อกของฉัน (การจัดรูปแบบที่ดีขึ้น)

ตัวอย่าง

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

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

อินพุต

iterables เป็นศูนย์หรือมากกว่านั้น [1] (เช่นรายการ, สตริง, tuple, พจนานุกรม)

เอาท์พุท (รายการ)

1st tuple = (element_1 ของตัวเลข, element_1 ของตัวอักษร)

tuple ตัวที่สอง = (ตัวเลข e_2, ตัวอักษร e_2)

...

n-th tuple = (ตัวเลข e_n, ตัวอักษร e_n)

  1. รายการของ tuples n: n คือความยาวของอาร์กิวเมนต์ที่สั้นที่สุด (อินพุต)
    • len (ตัวเลข) == 3 <len (ตัวอักษร) == 4 → short = 3 → return 3 tuples
  2. ความยาวแต่ละ tuple = # ของ args (tuple ใช้องค์ประกอบจากแต่ละ ARG)
    • args = (ตัวเลขตัวอักษร); len (args) == 2 → tuple พร้อม 2 องค์ประกอบ
  3. ith tuple = (element_i arg1, element_i arg2 …, element_i arg n)

คดีขอบ

1) สตริงว่าง: len (str) = 0 = ไม่มี tuples

2) สตริงเดี่ยว: len (str) == 2 tuples พร้อม len (args) == 1 องค์ประกอบ

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

Zip in Action!

1. สร้างพจนานุกรม [2] จากสองรายการ

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 เป็นโซลูชันที่หรูหราชัดเจนและรัดกุม

2. พิมพ์คอลัมน์ในตาราง

"*" [3] เรียกว่า "กำลังเปิดกล่องบรรจุ": 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')

เครดิตพิเศษ: การขยายไฟล์

zip(*args) เรียกว่า "การขยายไฟล์" เนื่องจากมีผลในทางกลับกัน 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 ของ tuple ซิปแต่ละอัน tuple_2 = e2 ของแต่ละรายการzipped

เชิงอรรถ

  1. วัตถุที่สามารถส่งคืนสมาชิกได้ครั้งละหนึ่งรายการ (เช่นรายการ [1,2,3] สตริง 'I like codin', tuple (1,2,3), พจนานุกรม {'a': 1, 'b' : 2})
  2. {key1: value1, key2: value2 ... }
  3. “ กำลังแกะกล่อง” (*)

* รหัส:

# 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

*เอาnumbers(1 arg) และ“ คลายไฟล์” องค์ประกอบที่ 2 ออกเป็น 2 ส่วน


14

โดยทั่วไปฟังก์ชั่นซิปใช้งานได้กับรายการสิ่งอันดับและพจนานุกรมใน Python หากคุณใช้ IPython ให้พิมพ์ zip? และตรวจสอบว่า zip () เกี่ยวกับอะไร

หากคุณไม่ได้ใช้ IPython ให้ติดตั้ง: "pip install ipython"

สำหรับรายการ

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

ผลลัพธ์คือ [('a', 'p'), ('b', 'q'), ('c', 'r')

สำหรับพจนานุกรม:

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

ผลลัพธ์คือ:

[('gaurav', 'amit'),
 ('nilesh', 'swapnil'),
 ('ramesh', 'anish'),
 ('anu', 'raghu')]

1
zip (c, d) กำลังแสดง zip (list (c), list (d))
Stephen Woodbridge

13

ในPython 3 zipจะส่งคืนตัววนซ้ำแทนและจะต้องถูกส่งผ่านไปยังฟังก์ชันลิสต์เพื่อรับการบีบอัดของ tuples

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

จากนั้นให้unzipพวกเขากลับมารวมกันตัววนซ้ำตัวซิป:

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

หากต้องการรูปแบบดั้งเดิมของรายการแทนที่จะเป็นสิ่งอันดับ:

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

1
แท็กคำถามระบุ Python 2.7 นี่สำหรับ Python 3 นอกจากนี้คำตอบนี้ได้กล่าวถึงไปแล้ว
0 0

8

เพื่อความครบถ้วนสมบูรณ์

เมื่อความยาวของรายการซิปไม่เท่ากัน ความยาวของรายการผลลัพธ์จะสั้นที่สุดโดยไม่มีข้อผิดพลาดเกิดขึ้น

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

1

ฉันไม่คิดว่าzipจะส่งคืนรายการ zipส่งกลับเครื่องกำเนิดไฟฟ้า คุณต้องทำlist(zip(a, b))เพื่อรับรายการสิ่งอันดับ

x = [1, 2, 3]
y = [4, 5, 6]
zipped = zip(x, y)
list(zipped)

1
แท็กคำถามระบุ Python 2.7 นี่สำหรับ Python 3 นอกจากนี้คำตอบนี้ได้กล่าวถึงไปแล้ว
0 0

1

มันน่าจะเพิ่มที่นี่เพราะมันเป็นคำถามที่มีอันดับสูงใน zip zipดีมาก Python ที่ใช้สำนวน แต่มันไม่ได้ปรับขนาดได้ดีนักสำหรับรายการขนาดใหญ่

แทน:

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

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

izipใช้ สำหรับการประมวลผลที่ทันสมัยจะเก็บไว้ในหน่วยความจำแคช L1 และมีประสิทธิภาพมากขึ้นสำหรับรายการขนาดใหญ่ ใช้เป็นเพียงแค่เพิ่มi:

for book, word in izip(books, words):
   print('{}: {}'.format(book, word))
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.