2011-05-26 19 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