繁体   English   中英

如何使用 zip 将数据分块成相等的绑定组?

[英]How can zip be used to chunk data into equal tied groups?

>>> n = 3
>>> x = range(n ** 2),
>>> xn = list(zip(*[iter(x)] * n))

PEP 618中,作者给出了如何使用zip将数据分块成相等大小的组的示例。

它是如何工作的?

我认为它依赖于zip的实现细节,这样如果它采用列表[iter(x)] * n n每个元素的第一个元素,则由于iter(x)因为每个元素都被取走。

这是因为以下代码复制了上述行为:

n = 3
x = range(n ** 2)
xn = [iter(x)] * n

res = []

while True:    
        try:    
                col = []    
                for element in xn:    
                        col.append(next(element))    
                res.append(col)    
        except:    
                break

但是,我想确保情况确实如此,并且这是一种可靠的行为,可用于对可迭代的元素进行分块。

它并不是真正特定于zip ,但你基本上有这个权利。 实际上,它压缩了对同一个迭代器的 3 个引用,导致它在它们之间循环。 在每次迭代期间,从迭代器中再消耗一个元素。

实际上,它与执行此操作相同:

>>> n = 3
>>> x = range(n ** 2)
>>> a = b = c = iter(x)
>>> list(zip(a, b, c))
[(0, 1, 2), (3, 4, 5), (6, 7, 8)]

请注意,它只会产生相同大小的组并且可能会丢弃元素(该部分是zip的特征,因为它受到最小可迭代的限制,尽管您可以根据需要使用itertools.zip_longest ):

>>> n = 4
>>> x = range(n ** 2)
>>> a = b = c = iter(x)
>>> list(zip(a, b, c))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, 13, 14)]

它不是zip的实现。 这就是可迭代对象在 Python 中的工作方式——它们总是“消耗”并继续前进。

例如:

whatever = iter([1, 2, 3])
next(whatever)
# 1
next(whatever)
# 2

zip所做的是“提前”它提供的每个 object 并给出您提供的示例[iter(x)] * n ... 这基本上变成了zip(whatever, whatever, whatever)

由于zip按顺序工作 - 它从whatever中获取第一个next - 然后从已经从第一个next移动的whatever内容中获取next ,所以它的值2 这意味着下一个是3 ETC...

这是设计的行为,语言保证了这一点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM