官方文档 https://docs.python.org/2/library/functions.html#zip 对 zip() 的说明如下 :
zip
([iterable, ...])
This function returns a list of tuples, where the i-th tuple contains the i-th element from each of the argument sequences or iterables. The returned list is truncated in length to the length of the shortest argument sequence. When there are multiple arguments which are all of the same length, zip()
is similar to map()
with an initial argument of None
. With a single sequence argument, it returns a list of 1-tuples. With no arguments, it returns an empty list.
The left-to-right evaluation order of the iterables is guaranteed. This makes possible an idiom for clustering a data series into n-length groups usingzip(*[iter(s)]*n)
.
zip()
in conjunction with the *
operator can be used to unzip a list:
>>> x = [1, 2, 3]
>>> y = [4, 5, 6]
>>> zipped = zip(x, y)
>>> zipped
[(1, 4), (2, 5), (3, 6)]
>>> x2, y2 = zip(*zipped)
>>> x == list(x2) and y == list(y2)
True
New in version 2.0.
Changed in version 2.4: Formerly, zip()
required at least one argument and zip()
raised a TypeError
instead of returning an empty list.
zip()是Python的一个内建函数,它接受一系列可迭代的对象作为参数,将对象中对应的元素按顺序组合成一个tuple,每个tuple中包含的是原有序列中对应序号位置的元素,然后返回由这些tuples组成的list。若传入参数的长度不等,则返回list的长度和参数中长度最短的对象相同。在所有参数长度相同的情况下,zip()与map()类似,没有参数的情况下zip()返回一个空list。
利用*号操作符,可以将list unzip(解压成单独的序列),基本示例如官方文档。
其它示例:
使用zip反转字典
>>> m = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
>>> m.items()
[('a', 1), ('c', 3), ('b', 2), ('d', 4)]
>>> zip(m.values(), m.keys())
[(1, 'a'), (3, 'c'), (2, 'b'), (4, 'd')]
>>> mi = dict(zip(m.values(), m.keys()))
>>> mi
{1: 'a', 2: 'b', 3: 'c', 4: 'd'}
另外对zip()这个不常用的函数也有一些高级用法:(转自http://www.cnblogs.com/diyunpeng/archive/2011/09/15/2177028.html)
比如我们有一个由列表描述的二维矩阵,通过python列表推导的方法,我们也能轻易完成这个任务
>>> a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> print [[row[col] for row in a] for col in range(len(a[0]))]
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
另外一种让人困惑的方法就是利用zip函数:
>>> a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> zip(*a)
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]
>>> map(list,zip(*a))
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
这种方法速度更快但也更难以理解,将list看成tuple解压,恰好得到我们“行列互换”的效果,再通过对每个元素应用list()函数,将tuple转换为list
>>> import random
>>>
>>> def random_pick(seq,probabilities):
... x = random.uniform(0, 1)
... cumulative_probability = 0.0
... for item, item_probability in zip(seq, probabilities):
... cumulative_probability += item_probability
... if x < cumulative_probability:
... break
... return item
...
>>> for i in range(15):
... print random_pick("abc",[0.1,0.3,0.6]),
...
c a a c a c c c b b c a c b b
这个函数有个限制,指定概率的列表必须和元素一一对应,而且和为1,否则这个函数可能不能像预想的那样工作。
稍微解释下,先利用random.uniform()函数生成一个0-1之间的随机数并复制给x,利用zip()函数将元素和他对应的概率打包成tuple,然后将每个元素的概率进行叠加,直到和大于x终止循环
这样,”a”被选中的概率就是x取值位于0-0.1的概率,同理”b”为0.1-0.4,”c”为0.4-1.0,假设x是在0-1之间平均取值的,显然我们的目的已经达到。