1、zip基本说明
zip
函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,返回由这些元组组成的列表。在Python3.x中为了减少内存,返回的是一个对象,可以用list()
转换来输出列表。
如果各个迭代器的元素个数不一样,则返回列表长度与最短的对象相同,利用*
号操作符,可以将元组解压为列表。
语法
1 | zip([iterable, ...]) |
- 参数:
- iterable:一个或多个迭代器;
- 返回值:
- 返回一个对象;
示例
1 | a = [1,2,3] |
2、一些使用
相邻元素压缩器
1 | a = [1, 2, 3, 4, 5, 6] |
首先理解迭代器,
iter()
可以将一个序列生成为一个迭代器,迭代器的特点是可以用for in
语句迭代。原理是迭代器对象有一个next
方法,可以每次移动迭代的指针,一旦迭代完,没有下一个元素的时候,会触发一个StopIteration
异常。迭代器的特点是,迭代了一次以后,指针就移动了,不会自动回溯。例如,可以用for in
迭代列表无数次,但只能迭代一次迭代器,如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
151, 2, 3, 4, 5, 6] a = [
x = iter(a)
for i in x:
print(i)
1
2
3
4
5
6
for i in x:
# 因为x已经被迭代过了,迭代的指针不会回溯,所以没有值了 print(i)
>>>而在上述相邻元素压缩器的使用过程中,可以发现:
1
2
3
4
5a = [1, 2, 3, 4, 5, 6]
[iter(a)] * 3
# [<listiterator at 0x7fa6c00ec1d0>,
# <listiterator at 0x7fa6c00ec1d0>,
# <listiterator at 0x7fa6c00ec1d0>]三个迭代器实际上是同一个迭代器。
再来理解
zip
,如前文所述,zip
将两个序列对应打包,如:1
2
3
41, 3, 5] a1 = [
2, 4, 6] a2 = [
list(zip(a1, a2))
[(1, 2), (3, 4), (5, 6)]而
*
则表示传入一个对象进行解包,如:1
2
3
4
5t = (a1, a2)
# 不加*号,zip 只有一个参数 t list(zip(t))
[([1, 3, 5],), ([2, 4, 6],)]
# 加*号的作用就是将元祖t,解包成a1,a2为zip的两个函数参数 list(zip(*t))
[(1, 2), (3, 4), (5, 6)]最后理解为什么使用迭代器,如下:
1
2
3
4
5
6
7
81, 2, 3, 4, 5, 6] a = [
x = iter(a)
t = [a, a]
# case 1,不使用迭代器 list(zip(*t))
[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]
tx = [x, x]
# case 2,使用迭代器 list(zip(*tx))
[(1, 2), (3, 4), (5, 6)]在case 1中,
zip
传入的两个参数a
,等于打包了两个列表,并在zip(*)
中进行解包,等价于:1
zip([1, 2, 3, 4, 5, 6],[1, 2, 3, 4, 5, 6])
在case 2中,
x
是迭代器对象,迭代过程会调用next
方法,迭代过一次后会自动移动且不会回溯。也就是说zip
执行过程中先调用第一个参数x
的next
方法得到参数1,再调用第二个参数x
的next
方法,上文我们已知这两个迭代器其实是同一个迭代器对象,所以第二次调用x
的next
方法时,迭代器指针已经移动,所以得到参数2,整个过程类似如下:1
2
3
4
5
6x.next -> 1
x.next -> 2
zip(x.next(), x.next()) ---> zip(1, 2)
x.next -> 3
x.next -> 4
zip(x.next(), x.next()) ---> zip(3, 4)等价于:
1
zip([1, 3, 5], [2, 4, 6])
基于此,就可以理解使用zip
做相邻元素压缩器的完整执行过程了。
列表元素依次相连
注意与
相邻元素压缩器
的效果区别。
1 | temp = ['a', 'b', 'c', 'd', 'e','f'] |
这个用法比较好理解,temp[:-1]
去除列表最后一个元素,temp[1:]
去除列表第一个元素,则上述过程等价于:
1 | zip(['a', 'b', 'c', 'd', 'e'], ['b', 'c', 'd', 'e', 'f']) |
基于该用法可衍生出多个元素依次相连的用法,如:
1 | list(zip(temp[:-2],temp[1:-1],temp[2:])) |
也可以用这种方法实现列表相邻元素压缩器的效果,如:
1 | a = [1, 2, 3, 4, 5, 6] |
取列表相同位置元素
1 | nums = ['flower','flow','flight'] |
反转字典
1 | m = {'a': 1, 'b': 2, 'c': 3, 'd': 4} |