2009-10-12 160 views
6

我是新的Python,並試圖以更加Pythonic和高效的方式實現代碼。 給定一個包含數字鍵和值的字典,找到非零值的最大鍵的最佳方法是什麼?找到非零值字典中最大關鍵字的有效方法

感謝

+0

也許您應該使用更合適的數據結構(例如堆)來檢索集合中的最小值/最大值。 – Juliet 2009-10-12 18:17:09

+1

「更多Pythonic」比什麼?你目前的解決方案是什麼?你不喜歡它什麼? – 2009-10-13 00:38:26

回答

12

像這樣的東西應該是相當快的:

>>> x = {0: 5, 1: 7, 2: 0} 
>>> max(k for k, v in x.iteritems() if v != 0) 
1 

(去除!= 0會稍微快一些還在,但有點模糊的意思)

+2

由於OP是新的,對發生的事情的描述也可能會有所幫助。 – 2009-10-12 18:03:06

+6

請注意,在Python 3.x中'.iteritems'不再存在,'.items'返回一個迭代器。 (與Python 2.x不同,'.items'返回一個列表,'.iteritems'返回一個迭代器。) – Stephan202 2009-10-12 18:22:30

+3

這裏發生了什麼?我們調用max()來查找最大的鍵。我們傳遞給max()的是「生成器表達式」,與「列表理解」非常相似。 max()會重複獲得k的值,並且它會選擇最大值。當v值不爲零時,生成器表達式將只返回k個值。 k和v值來自x.iteritems(),它返回鍵值對。這段代碼可以在Python 2.4或更新的版本中工作,但正如Stephan202指出的那樣,對於Python 3.x,您需要用「items」替換「iteritems」。 – steveha 2009-10-12 18:46:29

1

Python的最大功能需要「度量」函數的參數key=

data = {1: 25, 0: 75} 
def keymeasure(key): 
    return data[key] and key 

print max(data, key=keymeasure) 

使用內嵌拉姆達達到同樣的效果,並同時結合局部變量:

print max(data, key=(lambda k: data[k] and k)) 

最後的選擇在局部變量綁定到匿名鍵功能

print max(data, key=(lambda k, mapping=data: mapping[k] and k)) 
+1

該功能取決於對全局的訪問。餿主意。 – 2009-10-12 18:00:55

+1

不,它不。這隻取決於有權訪問相同的範圍。所有這些都可以在函數範圍內,它仍然可以工作。 – 2009-10-12 18:28:11

+2

@dalke,關鍵在於函數應該將字典作爲參數,而不是對字典的名稱進行硬編碼。 – steveha 2009-10-12 18:42:11

10

要得到最大的鑰匙,你可以使用max功能並檢查這樣的鑰匙:

max(x.iterkeys()) 

要過濾掉那些其中值是0,你可以使用一個generator expression

(k for k, v in x.iteritems() if v != 0) 

您可以結合這些讓你在找什麼(因爲max只有一個參數,周圍的括號發電機表達式可以刪除):

max(k for k, v in x.iteritems() if v != 0) 
+2

幾乎在那裏!最後,你刪除方括號,你留下了最好的解決方案。方括號創建一個列表理解,它構建了整個列表,然後整個列表被傳遞給max()。離開方括號,你會得到一個生成器表達式,它一次將值傳遞給max()。對於少數項目來說沒什麼大不了的,但對於非常大的字典來說,構建列表然後銷燬它的額外工作可能是相當大的。 – steveha 2009-10-12 18:20:03

+0

我剛更新了我的答案...從列表切換到生成器/迭代器 – 2009-10-12 18:28:28

+2

只是FYI,你不需要額外的parens。 max()的父類可以執行雙重任務:它們可以是調用max()的函數的父元素,也可以是生成器表達式周圍的元素。嘗試一下! :-) – steveha 2009-10-12 18:41:28

0

如果我是你,速度是一個大問題,我可能會創建一個新的容器類「DictMax」那將會跟蹤它最大的非零值元素通過具有ind的內部堆棧exes,堆棧的頂層元素始終是字典中最大元素的關鍵字。這樣你就可以每次在恆定時間獲得最大的元素。

相關問題