1 描述
zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。
也即:返回一个zip对象,此对象用于生成元组,此元组的个数由最小的可迭代对象决定
2 语法
zip([iterable/iterator, iterable/iterator, ...])
参数
iterable/iterator可以是迭代对象,也可以是迭代器
参数个数不限制,可以为一个,也可以是多个元素,
3 返回值
返回由元组为元素构成的对象——这是在python3中的现象
python3中的运行结果
>>> zip([1,2,3],[4,5,6]) <zip object at 0x7fcc3a709088>
python2中运行的结果
>>> a = zip([1,2,3],[4,5,6]) >>> a [(1, 4), (2, 5), (3, 6)] >>> print(a) [(1, 4), (2, 5), (3, 6)]
返回值的长度取决于元素中长度最短的那个对象
只有一个序列参数时,它返回一个1元组的列表。
names = ["中国移动", "中国电信", "中国联通"] for x in zip( names): print(x)
运行
('中国移动',) ('中国电信',) ('中国联通',)
4 实例
实例一:元素为迭代对象,迭代对象长度不一致
numbers = [10086, 10000, 10010, 95588] names = ["中国移动", "中国电信", "中国联通"] for x in zip(numbers, names): print(x) for x in zip(range(1,10000), numbers, names): print(x)
运行
(10086, '中国移动') (10000, '中国电信') (10010, '中国联通') (1, 10086, '中国移动') (2, 10000, '中国电信') (3, 10010, '中国联通')
注解:当zip()函数中的迭代对象长度不一致时,zip()返回值中元素长度与最短长度一致
实例二 含有迭代器的元素对象
numbers = [10086, 10000, 10010, 95588] names = ["中国移动", "中国电信", "中国联通"] z1 = zip(numbers, names) for x in z1: print(x) for x in zip(range(1,10000), iter(numbers), iter(names)): print(x)
运行
(10086, '中国移动') (10000, '中国电信') (10010, '中国联通') (1, 10086, '中国移动') (2, 10000, '中国电信') (3, 10010, '中国联通')
实例三 含有迭代器的元素对象
numbers = iter([10086, 10000, 10010, 95588]) names = ["中国移动", "中国电信", "中国联通"] z1 = zip(numbers, names) for x in z1: print(x) for x in zip(range(1,10000), numbers, names): print(x)
运行
(10086, '中国移动') (10000, '中国电信') (10010, '中国联通')
实例二和实例三中都使用了迭代器,而实际运行结果却相差较大,主要原因是迭代器的特点决定的,迭代器只能一直向后执行,不能后退;
在实例三中第一个for循环已经使用了迭代器numbers,所以再次执行时,不是从起始位置开始的,而是从上一个“指针”位置进行的。
为了更能说明问题,将代码修改进行
numbers = iter([11111, 10086, 10000, 10010, 22222, 33333, 44444, 55555, 66666,77777]) names = ["中国移动", "中国电信", "中国联通"] print(next(numbers)) for x in zip(numbers, names): print(x) print(next(numbers)) for x in zip(range(1,10000), iter(numbers), names): print(x)
运行结果
11111 (10086, '中国移动') (10000, '中国电信') (10010, '中国联通') 33333 (1, 44444, '中国移动') (2, 55555, '中国电信') (3, 66666, '中国联通')
这里面有一个问题一直没有解决,为什么zip()函数调用迭代器后,迭代器中“指针”跳过了元素22222,现在暂时没有找到原因。可能得在zip()源代码中找答案了。个人觉得在zip()函数中能不用迭代器就不用迭代器
实例四
a = [1, 2, 3] b = [4, 5, 6] for (x, y) in zip(a, b): print(x,"*",y,"=", x * y)
运行
1 * 4 = 4 2 * 5 = 10 3 * 6 = 18
补充
numbers = [10086, 10000, 10010, 95588] names = ['中国移动','中国电信','中国联通'] for x in zip(numbers,names): print(x) print("---------------------------") for x in zip(range(1,1000),numbers,names): print(x) print("---------------------------") for x,y,z in zip(range(1,1000),numbers,names): print("x:",x,'y:',y,'z:',z)
运行
(10086, '中国移动') (10000, '中国电信') (10010, '中国联通') --------------------------- (1, 10086, '中国移动') (2, 10000, '中国电信') (3, 10010, '中国联通') --------------------------- x: 1 y: 10086 z: 中国移动 x: 2 y: 10000 z: 中国电信 x: 3 y: 10010 z: 中国联通
对于 for x,y,z in zip(range(1,1000),numbers,names): 变量不对应,出现过多或者过少均不行
例如
numbers = [10086, 10000, 10010, 95588] names = ['中国移动','中国电信','中国联通'] for x,y in zip(range(1,1000),numbers,names): print("x:",x,'y:',y)
运行
Traceback (most recent call last): File "test.py", line 4, in <module> for x,y in zip(range(1,1000),numbers,names): ValueError: too many values to unpack (expected 2)
numbers = [10086, 10000, 10010, 95588] names = ['中国移动','中国电信','中国联通'] for x,y,z,k in zip(range(1,1000),numbers,names): print("x:",x,'y:',y,'z:',z)
运行
Traceback (most recent call last): File "test.py", line 5, in <module> for x,y,z,k in zip(range(1,1000),numbers,names): ValueError: not enough values to unpack (expected 4, got 3)