reddit上最近讨论了python zip的一些有趣用法,我结合文档整理了一下。
对>=2个list进行打包
这可以实现把两个list的元素组成为一个元组并形成新list;此时list中元素的顺序是保持不变的。
- list长度相等
In [18]: list(zip([1,2,3], [4,5,6]))
Out[18]: [(1, 4), (2, 5), (3, 6)]
- list长段长短不一,选短的
In [22]: list(zip([1,2,3], [4,5]))
Out[22]: [(1, 4), (2, 5)]
In [23]: list(zip([1,2], [3,4,5]))
Out[23]: [(1, 3), (2, 4)]
如果需要按长的进行zip,需使用itertools.zip_longest
In [35]: from itertools import zip_longest
In [36]: list(zip_longest([1,2], [3,4,5]))
Out[36]: [(1, 3), (2, 4), (None, 5)]
结合切片
这可以针对同一个list把元组错落打包。
In [24]: seq=[1,5,8,7]
In [25]: list(zip(seq, seq[1:]))
Out[25]: [(1, 5), (5, 8), (8, 7)]
使用*解包
*可以实现对zip的解包,
In [42]: x = [1, 2, 3]; y = [4, 5, 6]
In [43]: x2, y2 = zip(*zip(x, y))
In [44]: x2, y2
Out[44]: ((1, 2, 3), (4, 5, 6))
结合*可以对三元组进行翻转。
In [26]: grid = [
...: [1, 2, 3],
...: [4, 5, 6],
...: [7, 8, 9],
...: ]
In [27]: list(zip(*grid))
Out[27]: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
结合iter
In [28]: seq = [1, 2, 3, 4, 5, 6]
In [29]: seq_it = iter(seq)
In [30]: list(zip(seq_it, seq_it, seq_it))
Out[30]: [(1, 2, 3), (4, 5, 6)]
注意,此后的seq_it失效。
生成dict
两个list zip得到的iterator不仅可以生成list,还可以生成dict。当然这时候的顺序是无法保证的。
In [48]: list(zip([1,2,3], [4,5,6]))
Out[48]: [(1, 4), (2, 5), (3, 6)]
In [49]: dict(zip([1,2], [3,4,5]))
Out[49]: {1: 3, 2: 4}
In [50]: dict(zip([1,2,3], [4,5]))
Out[50]: {1: 4, 2: 5}