如何对集合中可变大小的部分求和?

时间:2017-12-22 19:34:58

标签: python python-3.x iterator aggregate generator-expression

我想计算一个集合的总和,用于不同大小的部分:

d = (1, 2, 3, 4, 5, 6, 7, 8, 9)
sz = (2, 3, 4)

# here I expect 1+2=3, 3+4+5=12, 6+7+8+9=30

itd = iter(d)
result = tuple( sum(tuple(next(itd) for i in range(s))) for s in sz )

print("result = {}".format(result))

我想知道我提出的解决方案是否是最多的' pythonic' (优雅,可读,简洁)实现我想要的方式...

特别是,我想知道是否有办法摆脱单独的迭代器' itd'以及是否更容易使用切片?

2 个答案:

答案 0 :(得分:2)

没有理由摆脱你的迭代器 - 毕竟迭代d就是你正在做的事情。

但是,您似乎在该代码中拥有过多的元组。通过摆脱它们,可以使所有工作的线条更清晰:

it = iter(d)
result = [sum(next(it) for _ in range(s)) for s in sz]
# [3, 12, 30]

...它具有额外的优势,即现在你生成一个列表而不是一个元组。顺便说一下,dsz也会将more sense作为列表:它们是同构数据的可变长度序列,而不是异构数据的固定长度序列。

另请注意,it是任意迭代器的常规名称,_是必须存在但从未实际使用过的任何变量的常规名称。

更进一步,next(it) for _ in range(s)正在做同样的工作islice()可以做得更清晰:

from itertools import islice

it = iter(d)
result = [sum(islice(it, s)) for s in sz]
# [3, 12, 30]

...在这一点上,我说代码的优雅,可读性和简洁性可能会得到。

答案 1 :(得分:1)

我会使用itertools.islice,因为您可以直接使用sz中的值作为每个点的步长:

>>> from itertools import islice
>>> it=iter(d)
>>> [sum(islice(it,s)) for s in sz]
[3, 12, 30]

然后,如果需要,您可以将其转换为元组。

当前需要iter才能在最后一个切片停止的位置逐步执行元组。否则每个切片将为d[0:s]