在python中查找列表的子集的总和

Posted

技术标签:

【中文标题】在python中查找列表的子集的总和【英文标题】:Find the sum of subsets of a list in python 【发布时间】:2011-09-02 06:28:41 【问题描述】:

这可能很简单,我忽略了一些东西......

我有一长串整数,在这种情况下代表网站的每日访问者。我想要一个每周访问者的新列表。所以我需要从原始列表中获取七组,将它们相加,然后将它们添加到新列表中。

我的解决方案似乎很暴力,不优雅:

numweeks = len(daily) / 7
weekly = []
for x in range(numweeks):
    y = x*7
    weekly.append(sum(visitors[y:y+7]))

有没有更有效或更 Pythonic 的方式来做到这一点?

【问题讨论】:

这实际上是 codereview.stackexchange.com 的一个好问题,它专门用于改进代码,使其更快/更优雅。 谢谢...不知道那个 stackexchange 网站。很难知道哪个适合哪个问题,特别是因为现在有这么多。另外,这个好像全是眼球,所以我总觉得原版最好。 :) 这段代码没有任何问题——它很简单并且很好地传达了它的意图。我只是将 var 名称更改为比 xy 更具描述性的名称,但除此之外,这比任何基于理解的 hack 更可取 不同之处在于,您会特别关注那些喜欢阅读他人代码以找出如何将事情做得更好的人。 【参考方案1】:

使用 itertools.islice:

weekly = [sum(list(itertools.islice(daily, i, i+7)))
          for i in range(0, len(daily), 7)]

编辑:

或者,使用 math.fsum:

weekly = [math.fsum(itertools.islice(daily, i, i+7))
          for i in range(0, len(daily), 7)]

【讨论】:

像这样使用 islice 不会很有效。您将每天以这种方式反复迭代元素。【参考方案2】:
weekly = [ sum(visitors[x:x+7]) for x in range(0, len(daily), 7)]

或者稍微不那么密集:

weekly = []
for x in range(0, len(daily), 7):
     weekly.append( sum(visitors[x:x+7]) )

或者,使用 numpy 模块。

by_week = numpy.reshape(visitors, (7, -1))
weekly = numpy.sum( by_week, axis = 1)

请注意,这要求访问者中的元素数量是 7 的倍数。它还要求您安装 numpy。但是,它可能也比其他方法更有效。

或者对于 itertools 代码奖励:

def grouper(n, iterable, fillvalue=None):
    "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return itertools.izip_longest(fillvalue=fillvalue, *args)

weekly = map(sum, grouper(7, visitors, 0))

【讨论】:

+1 包括 itertools.izip_longest 案例,我希望你没有,所以我可以提一下。 :-) 另外,对于大量访问者或者如果访问者是生成器,itertools.izip_longest 和 itertools.imap 选项更有效,我会使用 xrange 而不是 range在第一个例子中调用。【参考方案3】:
>>> daily = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
>>> print [sum(daily[x:x+7]) for x in range(0, len(daily), 7)]
[28, 77, 105]

我不确定这是否是“pythonic”,但我真的很喜欢 python 的这种单行内容。

血腥细节:Comprehensions

【讨论】:

以上是关于在python中查找列表的子集的总和的主要内容,如果未能解决你的问题,请参考以下文章

使用动态编程从 Python 上的子集总和问题中获取所有子集

如何在python中的字典列表中查找项目的累积总和

带有 2675 个数字列表的子集总和

查找列表中哪个数字总和等于某个数字的算法

使用 lambda 函数在嵌套列表中查找总和

查找具有给定总和的数字列表的所有组合