How does zip(*[iter(s)]*n) work in Python?
1 2 3 4 | s = [1,2,3,4,5,6,7,8,9] n = 3 zip(*[iter(s)]*n) # returns [(1,2,3),(4,5,6),(7,8,9)] |
1 2 | x = iter([1,2,3,4,5,6,7,8,9]) print zip(x, x, x) |
另一个很好的答案和注释很好地解释了参数解包和zip()的作用。
正如Ignacio和Ujukatzel所说,传递给
1 2 3 4 | 1,2,3,4,5,6,7,8,9 1,2,3,4,5,6,7,8,9 1,2,3,4,5,6,7,8,9 ^ ^ ^ ^ ^ ^ ^ ^ ^ |
由于您需要更详细的代码示例:
1 2 3 4 5 6 7 | chunk_size = 3 L = [1,2,3,4,5,6,7,8,9] # iterate over L in steps of 3 for start in range(0,len(L),chunk_size): # xrange() in 2.x; range() in 3.x end = start + chunk_size print L[start:end] # three-item chunks |
根据
1 2 3 | [0:3) #[1,2,3] [3:6) #[4,5,6] [6:9) #[7,8,9] |
fwiw,你可以用
1 2 | >>> map(None,*[iter(s)]*3) [(1, 2, 3), (4, 5, 6), (7, 8, 9)] |
有关
我认为在所有答案中遗漏了一件事(对于熟悉迭代器的人来说可能是显而易见的),但对其他人来说却不那么明显-
因为我们有相同的迭代器,所以它被使用,其余的元素由zip使用。所以如果我们只是使用列表而不是ITER如。
1 2 3 4 | l = range(9) zip(*([l]*3)) # note: not an iter here, the lists are not emptied as we iterate # output [(0, 0, 0), (1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4), (5, 5, 5), (6, 6, 6), (7, 7, 7), (8, 8, 8)] |
使用迭代器,弹出值并只保留剩余的可用性,因此对于使用了0的zip,1可用,然后2可用,依此类推。一件非常微妙的事情,但相当聪明!!!!
因此,在执行
用这种方式使用zip的一句建议。如果列表的长度不可等分,它将截断列表。要解决这个问题,如果您可以接受填充值,那么您可以使用itertools.izip_longst。或者你可以用这样的东西:
1 2 3 4 | def n_split(iterable, n): num_extra = len(iterable) % n zipped = zip(*[iter(iterable)] * n) return zipped if not num_extra else zipped + [iterable[-num_extra:], ] |
用途:
1 2 | for ints in n_split(range(1,12), 3): print ', '.join([str(i) for i in ints]) |
印刷品:
1 2 3 4 | 1, 2, 3 4, 5, 6 7, 8, 9 10, 11 |
在python解释器或
1 2 | In [35]: [iter("ABCDEFGH")]*2 Out[35]: [<iterator at 0x6be4128>, <iterator at 0x6be4128>] |
所以,我们有两个迭代器的列表,它们指向同一个迭代器对象。记住,一个对象上的
此外,
1 2 3 4 5 6 7 8 9 | In [41]: help(zip) Help on built-in function zip in module __builtin__: zip(...) zip(seq1 [, seq2 [...]]) -> [(seq1[0], seq2[0] ...), (...)] Return a list of tuples, where each tuple contains the i-th element from each of the argument sequences. The returned list is truncated in length to the length of the shortest argument sequence. |
解包(
这可以扩展到所述的