179

我正在尝试学习如何“压缩”列表。为此,我有一个程序,在某个特定点,我执行以下操作:

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

这给了我三个列表,x1x2x3,每个列表,例如,大小为 20。

现在,我这样做:

zipall = zip(x1, x2, x3)

但是,当我这样做时:

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

我得到了 20,这不是我所期望的。我预计三个。我认为我做的事情根本上是错误的。

4

10 回答 10

259

当您zip()将三个列表组合在一起时,每个列表包含 20 个元素,结果有 20 个元素。每个元素都是一个三元组。

你自己看:

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

要找出每个元组包含多少个元素,您可以检查第一个元素的长度:

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

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

当然,如果列表一开始是空的,这将不起作用。

于 2012-12-04T14:15:11.510 回答
72

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

并将它们“压缩”到一个列表中,其条目为 3-tuples (ai, bi, ci)。想象一下从左到右水平画一条拉链。

于 2012-12-04T14:18:25.857 回答
43

在 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))
于 2015-05-01T00:37:23.347 回答
29

zip创建一个新列表,其中填充包含来自可迭代参数的元素的元组:

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

我希望您尝试创建一个元组,其中每个元素都是一个列表。

于 2012-12-04T14:17:12.327 回答
20

Python 3 zip中,它返回一个迭代器,并且需要传递给一个列表函数来获取压缩元组:

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']
于 2018-05-27T14:17:29.900 回答
14

来源:我的博客文章(更好的格式)

例子

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

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

输入

零个或多个可迭代对象 [1](例如列表、字符串、元组、字典)

输出(列表)

第一个元组=(数字元素_1,字母元素_1)

第二个元组 =(e_2 个数字,e_2 个字母)

n-th tuple = (e_n 个数字, e_n 个字母)

  1. n 元组列表:n 是最短参数(输入)的长度
    • len(numbers) == 3 < len(letters) == 4 → short= 3 → 返回 3 个元组
  2. 每个元组的长度 = # of args(元组从每个 arg 中获取一个元素)
    • args =(数字,字母);len(args) == 2 → 包含 2 个元素的元组
  3. i元组 = (element_i arg1, element_i arg2…, element_i arg n)

边缘案例

1) 空字符串:len(str)= 0 = 没有元组

2) 单个字符串:len(str) == 2 个元组,其中 len(args) == 1 个元素

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

拉链在行动!

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_2 = 每个的 e2zipped

脚注

  1. 一个能够一次返回一个成员的对象(例如列表 [1,2,3]、字符串 'I like codin'、元组 (1,2,3)、字典 {'a':1、'b' :2})
  2. {键1:值1,键2:值2 ...}
  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 个 args

于 2017-05-25T17:37:19.850 回答
13

Basically the zip function works on lists, tuples and dictionaries in Python. If you are using IPython then just type zip? And check what zip() is about.

If you are not using IPython then just install it: "pip install ipython"

For lists

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

The output is [('a', 'p'), ('b', 'q'), ('c', 'r')

For dictionary:

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

The output is:

[('gaurav', 'amit'),
 ('nilesh', 'swapnil'),
 ('ramesh', 'anish'),
 ('anu', 'raghu')]
于 2014-07-19T19:17:55.253 回答
8

为了完整起见。

当压缩列表的长度不相等时。结果列表的长度将成为最短的,没有任何错误发生

>>> a = [1]
>>> b = ["2", 3]
>>> zip(a,b)
[(1, '2')]
于 2016-11-20T21:52:56.507 回答
5

值得在这里添加,因为它是 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))
于 2020-02-23T13:57:22.767 回答
1

我认为不会zip返回列表。zip返回一个生成器。你必须做得到list(zip(a, b))一个元组列表。

x = [1, 2, 3]
y = [4, 5, 6]
zipped = zip(x, y)
list(zipped)
于 2018-05-08T15:23:18.463 回答