我有一个生成器,它在每次迭代中返回一个列表。列表的每个元素可以是 0 或 1。我想计算返回的元素总数(包括 0 和 1)和返回的 1 的总数。我尝试使用这样的 reduce 函数来实现:
t = reduce( (lambda x,y:(y[0]+1,y[1]+x)), gen_fn(), (0,0))
上面的 gen_fn() 是生成器,它在每个 yield 语句中返回列表的一部分。我想通过用元组 (0,0) 进行初始化来实现它。鉴于从生成器返回的元素如下:
[0, 1, 1, 0, 1]
我对 t 的预期输出是 (5,3)。但是我的代码失败并显示此错误消息:
TypeError: unsupported operand type(s) for +: 'int' and 'tuple'
谁能帮我找出问题所在?我对 reduce 和 lambda 函数缺乏经验使我无法弄清楚自己做错了什么。提前致谢。
最佳答案
我认为最好的答案是保持简单:
count = 0
total = 0
for item in gen_fn():
count += 1
total += item
在这里使用 reduce()
只会降低代码的可读性。
如果你的问题是代码高尔夫并且你想要一个单行(同时保持惰性评估),那么你想要:
count, total = collections.deque(zip(itertools.count(1), itertools.accumulate(gen_fn())), maxlen=1).pop()
当然,如果您选择这样的结构而不是简单的解决方案,您会很生气。
编辑:
如果生成器产生多个较小的部分,则只需使用 itertools.chain.from_iterable(gen_fn())
将其展平。
关于生成器上的 Python 聚合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23529432/