python - itertools 中的 grouper() 示例
问题描述
我是python的新手。在阅读 python 标准库参考时,我对 itertools recipes 部分中的 grouper() 示例感到困惑。
我试图将示例代码放在一个小程序中,如下所示:
from itertools import zip_longest
import copy
def grouper(iterable, n, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
args = [iter(iterable)] * n
# print each string in args
#c = copy.deepcopy(args)
#for a in c:
# print(list(a))
return zip_longest(*args, fillvalue=fillvalue)
def main():
print("this is our first test script file")
g = grouper('ABCDEFG', 3, 'x')
# print each string in results
#for s in g:
# print(list(s))
main()
如果我们删除评论标签,它会产生如下结果:
['A', 'B', 'C', 'D', 'E', 'F', 'G']
[]
[]
['A', 'B', 'C']
['D', 'E', 'F']
['G', 'x', 'x']
这对我来说看起来不对,因为 args 变量的结果是:
['A', 'B', 'C', 'D', 'E', 'F', 'G']
[]
[]
zip_longest() 调用如何产生如下结果?
['A', 'B', 'C']
['D', 'E', 'F']
['G', 'x', 'x']
它应该是 A,B,C,D,... 因为 args 中的第二个和第三个列表是空的。还是我错过了什么?
谁能给我解释一下?
解决方案
zip
并且与他们如何使用他们的论点zip_longest
完全不同。deepcopy
grouper
之所以有效,是因为每次从每个参数zip
中zip_longest
获取一个元素。例如,考虑一下:
i1 = i2 = i3 = iter([1, 2, 3, 4, 5, 6])
zip(i1, i2, i3)
因为i1
, i2
, 和i3
共享相同的迭代器,所以推进一个迭代器也会推进另一个迭代器。zip
做这个:
- 从 中取一个元素
i1
。 - 从 中取一个元素
i2
。 - 从 中取一个元素
i3
。 - 产生这些元素的元组。
- 从步骤 1 开始重复。
例如,会发生这样的事情:
第一次迭代:
- 从 中取一个元素
i1
。=>1
- 从 中取一个元素
i2
。=>2
- 从 中取一个元素
i3
。=>3
- 产生这些元素的元组 =>
(1, 2, 3)
第二次迭代:
- 从 中取一个元素
i1
。=>4
- 从 中取一个元素
i2
。=>5
- 从 中取一个元素
i3
。=>6
- 产生这些元素的元组 =>
(4, 5, 6)
现在,deepcopy
在这种情况下,只复制迭代器。它不会以任何方式消耗它们。但是,您的for
循环确实会消耗它们:
- 从
i1
. =>1, 2, 3, 4, 5, 6, StopIteration raised
- 从
i2
. =>StopIteration raised
- 从
i3
. =>StopIteration raised
因此,您会得到您所看到的结果。
推荐阅读
- asp.net-mvc-4 - 当页面加载动作结果在 mvc 中调用两次时
- c# - 如何从像素更改红色/绿色/蓝色/alpha 值的值
- html - 如何使按钮仅在移动设备上双击时激活,但在桌面上单击时激活?
- php - 如何使用 laravel 5.4 通过 jQuery/ajax 创建登录/注销
- heroku - Heroku免费测功机
- php - 如何在调用者文件之外正确调用 css 文件夹?
- node.js - MongoDB Atlas - 如何修复共享网络托管上的“TransientTransactionError”
- python - 使用 Python pandas 根据条件将行值复制到另一列
- java - 如何修复说明一个包可被多个模块访问的 java 错误
- javascript - javascript缩小后找不到变量