2010-08-05 109 views
4

我得到了以下詞典:總結陣列的字典在Python

mydict = { 
    'foo': [1,19,2,3,24,52,2,6],   # sum: 109 
    'bar': [50,5,9,7,66,3,2,44],   # sum: 186 
    'another': [1,2,3,4,5,6,7,8],   # sum: 36 
    'entry': [0,0,0,2,99,4,33,55],  # sum: 193 
    'onemore': [21,22,23,24,25,26,27,28] # sum: 196 
} 

我需要有效地過濾出並通過陣列的總和的前x條目進行排序。

例如,前3名排序過濾列表上面的例子是

sorted_filtered_dict = { 
    'onemore': [21,22,23,24,25,26,27,28], # sum: 196 
    'entry': [0,0,0,2,99,4,33,55],  # sum: 193 
    'bar': [50,5,9,7,66,3,2,44]   # sum: 186 
} 

我是相當新的Python和嘗試過自己與鏈接之和過濾功能在lambda函數上,但與實際的語法掙扎。

回答

7

這很容易用一種做:

sorted(mydict.iteritems(), key=lambda tup: sum(tup[1]), reverse=True)[:3] 

這是合理的,如果該比率與此類似(3/5)。如果它更大,你會想避免排序(O(n log n)),因爲前3可以在O(n)中完成。例如,使用heapq,堆模塊:

heapq.nlargest(3, mydict.iteritems(), key=lambda tup: sum(tup[1])) 

這是O(n + 3 log n)的,因爲組件中的初始堆爲O(n),並重新heapifying是O(log n)的。

編輯:如果你正在使用Python 2.7或更高版本,可以很容易地轉換爲OrderedDictequivalent version爲Python 2.4及以上):

OrderedDict(heapq.nlargest(3, mydict.iteritems(), key=lambda tup: sum(tup[1]))) 

OrderedDict具有相同的API dict,但記得插入順序。

+0

你如何爲O(n + 3 log n)的,它應該是O(N日誌K),或者當k = 3恆取消出來,你會得到O(n) – 2010-08-05 14:18:09

+0

在我的現實世界的例子中,它是幾十萬的前100名,因此heapq的例子可能是首選。謝謝。 – poezn 2010-08-05 17:43:08

+0

只是意識到這不會給我一個字典,但一組數組。有任何想法嗎? – poezn 2010-08-05 20:52:02

2

對於這樣一個小片不值得使用islice

sorted(mydict.iteritems(), key=lambda (k,v): sum(v), reverse=True)[:3]