2011-05-26 96 views
8

这可能是很简单,我俯瞰东西...查找列表的子集的总和蟒蛇

我有一个整数一长串,在此情况下表示每天游客到网站。我想每周访客的新名单。所以我需要从原始列表中获得七个组,并将它们相加,然后将它们添加到新列表中。

我的解决办法似乎很蛮力,不雅:

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

是否有这样做的更有效,更Python的方式?

+1

其实,这是一个很好的codereview.stackexchange.com是sp。的问题特别是为了改进代码,使其更快/更优雅。 – 2011-05-26 03:47:47

+0

谢谢......不知道那个stackexchange网站。很难知道哪一个问题适合哪个问题,尤其是因为现在有这么多。另外,这个似乎有所有的眼球,所以我总是觉得原来是最好的。 :) – fitzgeraldsteele 2011-05-26 03:52:15

+0

这段代码没有错 - 它很直接,并且很好地传达了它的意图。我只是将var名称更改为比'x'和'y'更具描述性的内容,但除此之外,这比任何基于理解的破解更有优势 – 2011-05-26 03:52:23

回答

10
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)) 
+0

用于将'y = x * 7'替换为'range()'的另一个参数。 – John 2011-05-26 04:04:13

+0

+1包括itertools.izip_longest的情况,我希望你没有,所以我可以提及它。 :-) – 2011-05-26 08:47:47

+0

此外,对于大量访问者或者访问者是生成器,itertools.izip_longest和itertools.imap选项更高效,我会在第一个中使用“xrange”而不是“range”调用例。 – 2011-05-26 08:52:40

0
>>> 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] 

我不知道这是否是“Python的”,但我真正爱的蟒蛇这一行的东西。

血淋淋的细节:Comprehensions

0

使用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)] 
+0

使用像这样的islice不会是非常有效的。您将以这种方式重复每日重复元素。 – 2011-05-26 13:41:48