gpt4 book ai didi

python - itertools "grouper"函数配方如何工作?

转载 作者:太空宇宙 更新时间:2023-11-03 15:47:26 24 4
gpt4 key购买 nike

从这里开始: https://docs.python.org/3/library/itertools.html#itertools-recipes

def grouper(iterable, n, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
return zip_longest(*args, fillvalue=fillvalue)

我理解 zip_longest 调用。但我没有得到:

args = [iter(iterable)] * n

如果稍后要将可迭代对象传递到 izip_longest 中,为什么还要再次将可迭代对象包装到 iter() 中呢?我不能这样做吗:

args = [iterable] * n

但似乎没有iter(),它只是将同一个迭代器重复n次。但是把它放在 iter() 中如何改变它的行为呢?

最佳答案

这种分组利用了迭代器的单次传递特性(与单纯的可迭代对象相反,它可以潜在地迭代多次,并且在非迭代器可迭代对象上使用 iter 应该返回一个新的独立迭代器。相比之下,在迭代器上调用 iter 返回迭代器本身

所以这是一个只接受两个参数的 zip 函数的简单实现:

In [1]: def myzip(x, y):
...: itx, ity = iter(x), iter(y)
...: while True:
...: try:
...: a, b = next(itx), next(ity)
...: except StopIteration:
...: return
...: yield a, b
...:

In [2]: list(zip('abcd','efgh'))
Out[2]: [('a', 'e'), ('b', 'f'), ('c', 'g'), ('d', 'h')]

In [3]: list(myzip('abcd','efgh'))
Out[3]: [('a', 'e'), ('b', 'f'), ('c', 'g'), ('d', 'h')]

这几乎就是内置 zip 的工作原理。现在,如果我们将列表作为可迭代项来执行上述操作会怎么样?

In [16]: mylist = [1,2,3,4]

In [17]: iterable = mylist

In [18]: itx, ity = iter(iterable), iter(iterable)

In [19]: itx is ity
Out[19]: False

In [20]: next(itx), next(ity)
Out[20]: (1, 1)

In [21]: next(itx), next(ity)
Out[21]: (2, 2)

In [22]: next(itx), next(ity)
Out[22]: (3, 3)

In [23]: next(itx), next(ity)
Out[23]: (4, 4)

In [24]: next(itx), next(ity)
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-24-b6cbb26d280f> in <module>()
----> 1 next(itx), next(ity)

StopIteration:

但是,如果 iterable 是一个迭代器:

In [25]: iterable = iter(mylist)

In [26]: itx, ity = iter(iterable), iter(iterable)

In [27]: itx is ity
Out[27]: True

In [28]: next(itx), next(ity)
Out[28]: (1, 2)

In [29]: next(itx), next(ity)
Out[29]: (3, 4)

In [30]: next(itx), next(ity)
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-30-b6cbb26d280f> in <module>()
----> 1 next(itx), next(ity)

StopIteration:

最后,请注意序列上的 repition 永远不会复制序列的元素,因此执行 [iter(x)]*n 会返回一个列表,其中包含 n 个对同一迭代器的引用,因此:

In [32]: args = [iter(mylist)]*3

In [33]: args
Out[33]:
[<list_iterator at 0x1040c9320>,
<list_iterator at 0x1040c9320>,
<list_iterator at 0x1040c9320>]

注意,它们是相同的 list_iterator 对象...

关于python - itertools "grouper"函数配方如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49180862/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com