0. zip 的特殊情况
-
不等长:
a = range(3) b = range(5) >> list(zip(a, b)) [(0, 0), (1, 1), (2, 2)]
-
zip(*)
*
对其作用的对象进行 unpack,拆包;
l = [[1, 2, 3], [4, 5, 6]] >> list(zip(l)) [([1, 2, 3],), ([4, 5, 6],)] >> list(zip(*l)) [(1, 4), (2, 5), (3, 6)]
1. 两层循环与 zip 的一一对应
[(i, j) for i in x for j in y]
也即:
l = []
for i in x:
for j in y:
l.append((i, j))
表达的是一种笛卡尔积的关系。那么如何实现一一对应呢,这时就需要zip操作了:
>>> [(i, j) for i, j in zip(x, y)]
[(0, 'a'),
(1, 'b'),
...
(24, 'y'),
(25, 'z')]
2. meshgrid
不由得让人联想起meshgrid函数,我们要实现`[0, 1, 2, 3, 4, 5] × \times ×[0, 1, 2, 3, 4, 5]网格的整数节点位置:
>>> [Y, X] = np.meshgrid(range(0, 6), range(0, 6))
>>> Y
array([[0, 1, 2, 3, 4, 5],
[0, 1, 2, 3, 4, 5],
[0, 1, 2, 3, 4, 5],
[0, 1, 2, 3, 4, 5],
[0, 1, 2, 3, 4, 5],
[0, 1, 2, 3, 4, 5]])
>>> X
array([[0, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1],
[2, 2, 2, 2, 2, 2],
[3, 3, 3, 3, 3, 3],
[4, 4, 4, 4, 4, 4],
[5, 5, 5, 5, 5, 5]])
for x in range(0, 6):
for y in range(0, 6):
x - y
便可转换为矩阵化的做法:
X-Y
3. 二元tuple元素前后的调换
我们再次回到zip本身,如何实现一个list(tuple)前后元素的调换再集合:
[1, 2, 3, 4, 5] -> [(2, 1), (3, 2), (4, 3), (5, 4)]
对一个list做两次索引再zip:
>>> l = [1, 2, 3, 4, 5]
>>> [(j, i) for i, j in zip(l[:-1], l[1:])]
[(2, 1), (3, 2), (4, 3), (5, 4)]