3

我想为不同大小的部分计算集合的总和:

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”,以及使用切片是否更容易?

4

2 回答 2

2

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

不过,您似乎确实在该代码中有过多的元组。通过摆脱它们,可以使完成所有工作的行更清晰:

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

…它还有一个额外的优势,那就是现在您正在生成一个列表而不是一个元组。d顺便说一下,作为列表sz更有意义:它们是同质数据的可变长度序列,而不是异构数据的固定长度序列。

另请注意,这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]

......在这一点上,我会说代码尽可能优雅、易读和简洁。

于 2017-12-23T21:04:31.863 回答
2

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

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

Then you can convert that to a tuple if needed.

The iter is certainly needed in order to step through the tuple at the point where the last slice left off. Otherwise each slice would be d[0:s]

于 2017-12-23T23:15:45.133 回答