I want to calculate the sum of a collection, for sections of different sizes:
我想计算一个集合的总和,用于不同大小的部分:
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))
I wonder whether the solution I came up with is the most 'pythonic' (elegant, readable, concise) way to achieve what I want...
我想知道我想出的解决方案是否是实现我想要的最'pythonic'(优雅,可读,简洁)的方式...
In particular, I wonder whether there is a way to get rid of the separate iterator 'itd', and whether it would be easier to work with slices?
特别是,我想知道是否有办法摆脱单独的迭代器'itd',以及是否更容易使用切片?
2 个解决方案
#1
1
I would use itertools.islice since you can directly use the values in sz
as the step size at each point:
我会使用itertools.islice,因为你可以直接使用sz中的值作为每个点的步长:
>>> 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]
当然需要iter才能在最后一个切片停止的位置逐步通过元组。否则每个切片都是d [0:s]
#2
2
There's no reason to get rid of your iterator – iterating over d
is what you are doing, after all.
没有理由摆脱你的迭代器 - 毕竟迭代d是你正在做的事情。
You do seem to have an overabundance of tuples in that code, though. The line that's doing all the work could be made more legible by getting rid of them:
但是,您似乎在该代码中拥有过多的元组。通过摆脱它们,可以使所有工作的线更清晰:
it = iter(d)
result = [sum(next(it) for _ in range(s)) for s in sz]
# [3, 12, 30]
… which has the added advantage that now you're producing a list rather than a tuple. d
and sz
also make more sense as lists, by the way: they're variable-length sequences of homogeneous data, not fixed-length sequences of heterogeneous data.
...它具有额外的优势,现在你正在生成一个列表而不是一个元组。顺便提一下,d和sz作为列表更有意义:它们是同构数据的可变长度序列,而不是异构数据的固定长度序列。
Note also that it
is the conventional name for an arbitrary iterator, and _
is the conventional name for any variable that must exist but is never actually used.
另请注意,它是任意迭代器的常规名称,_是必须存在但从未实际使用过的任何变量的常规名称。
Going a little further, next(it) for _ in range(s)
is doing the same work that islice()
could do more legibly:
更进一步,下一个(它)为_在范围内是做同样的工作,islice()可以做得更清晰:
from itertools import islice
it = iter(d)
result = [sum(islice(it, s)) for s in sz]
# [3, 12, 30]
… at which point, I'd say the code's about as elegant, readable and concise as it's likely to get.
...在这一点上,我会说代码的优雅,可读和简洁,因为它可能会得到。
#1
1
I would use itertools.islice since you can directly use the values in sz
as the step size at each point:
我会使用itertools.islice,因为你可以直接使用sz中的值作为每个点的步长:
>>> 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]
当然需要iter才能在最后一个切片停止的位置逐步通过元组。否则每个切片都是d [0:s]
#2
2
There's no reason to get rid of your iterator – iterating over d
is what you are doing, after all.
没有理由摆脱你的迭代器 - 毕竟迭代d是你正在做的事情。
You do seem to have an overabundance of tuples in that code, though. The line that's doing all the work could be made more legible by getting rid of them:
但是,您似乎在该代码中拥有过多的元组。通过摆脱它们,可以使所有工作的线更清晰:
it = iter(d)
result = [sum(next(it) for _ in range(s)) for s in sz]
# [3, 12, 30]
… which has the added advantage that now you're producing a list rather than a tuple. d
and sz
also make more sense as lists, by the way: they're variable-length sequences of homogeneous data, not fixed-length sequences of heterogeneous data.
...它具有额外的优势,现在你正在生成一个列表而不是一个元组。顺便提一下,d和sz作为列表更有意义:它们是同构数据的可变长度序列,而不是异构数据的固定长度序列。
Note also that it
is the conventional name for an arbitrary iterator, and _
is the conventional name for any variable that must exist but is never actually used.
另请注意,它是任意迭代器的常规名称,_是必须存在但从未实际使用过的任何变量的常规名称。
Going a little further, next(it) for _ in range(s)
is doing the same work that islice()
could do more legibly:
更进一步,下一个(它)为_在范围内是做同样的工作,islice()可以做得更清晰:
from itertools import islice
it = iter(d)
result = [sum(islice(it, s)) for s in sz]
# [3, 12, 30]
… at which point, I'd say the code's about as elegant, readable and concise as it's likely to get.
...在这一点上,我会说代码的优雅,可读和简洁,因为它可能会得到。