2012-05-08 162 views
57

我:基於其相應的值如何篩選字典鍵

dictionary = {"foo":12, "bar":2, "jim":4, "bob": 17} 

我要遍歷該字典,但在價值觀,而不是鑰匙,所以我可以在其他功能使用的值。

例如,我要測試的字典值比6大,然後鑰匙存放在列表中。我的代碼如下所示:

list = [] 
for c in dictionary: 
    if c > 6: 
     list.append(dictionary[c]) 
print list 

,然後,在一個完美的世界,list將其特徵值大於6更大所有的按鍵。 但是,我的for循環只遍歷鍵;我想將其改爲價值觀!

任何幫助,非常感謝。 謝謝

+1

這個問題的標題應該因爲你真正想實現(什麼改變和答案反映了這一)獲取某個子句爲真的字典中相應值的鍵。像「如何根據其對應值過濾字典鍵」可能是更好的選擇。 – glarrain

回答

81
>>> d = {"foo": 12, "bar": 2, "jim": 4, "bob": 17} 
>>> [k for k, v in d.items() if v > 6] # Use d.iteritems() on python 2.x 
['bob', 'foo'] 

我想只更新這個答案也展示由@glarrain,我發現自己傾向於時下使用該解決方案。

[k for k in d if d[k] > 6] 

這是完全交兼容,並且不需要從.iteritems一個令人困惑的變化(.iteritems避免保存的列表上的Python 2存儲器,其被固定在Python 3).items

@ Prof.Falken提到了解決這一問題的

from six import iteritems 

,有效地解決了跨兼容性問題,但需要你下載軟件包six

但是我不會完全@glarrain同意這個解決方案更具可讀性,即使Python應該只有一種方法來進行辯論,也可能只是個人偏好。在我看來,這取決於情況(例如,你可能有一個長字典名稱,你不想輸入兩次,或者你想給這些值更易讀的名字或其他原因)

10一些有趣的計時:

在Python 2中,第二溶液是更快,在Python 3它們在原始速度幾乎完全相等。


$ python -m timeit -s 'd = {"foo": 12, "bar": 2, "jim": 4, "bob": 17};' '[k for k, v in d.items() if v > 6]' 
1000000 loops, best of 3: 0.772 usec per loop 
$ python -m timeit -s 'd = {"foo": 12, "bar": 2, "jim": 4, "bob": 17};' '[k for k, v in d.iteritems() if v > 6]' 
1000000 loops, best of 3: 0.508 usec per loop 
$ python -m timeit -s 'd = {"foo": 12, "bar": 2, "jim": 4, "bob": 17};' '[k for k in d if d[k] > 6]' 
1000000 loops, best of 3: 0.45 usec per loop 

$ python3 -m timeit -s 'd = {"foo": 12, "bar": 2, "jim": 4, "bob": 17};' '[k for k, v in d.items() if v > 6]' 
1000000 loops, best of 3: 1.02 usec per loop 
$ python3 -m timeit -s 'd = {"foo": 12, "bar": 2, "jim": 4, "bob": 17};' '[k for k in d if d[k] > 6]' 
1000000 loops, best of 3: 1.02 usec per loop 

然而這些都只是針對小字典測試,巨大字典我敢肯定,沒有一個字典鍵查找(d[k])將使.items快得多。 這似乎是這樣

$ python -m timeit -s 'd = {i: i for i in range(-10000000, 10000000)};' -n 1 '[k for k in d if d[k] > 6]' 
1 loops, best of 3: 1.75 sec per loop 
$ python -m timeit -s 'd = {i: i for i in range(-10000000, 10000000)};' -n 1 '[k for k, v in d.iteritems() if v > 6]' 
1 loops, best of 3: 1.71 sec per loop 
$ python3 -m timeit -s 'd = {i: i for i in range(-10000000, 10000000)};' -n 1 '[k for k in d if d[k] > 6]' 
1 loops, best of 3: 3.08 sec per loop 
$ python3 -m timeit -s 'd = {i: i for i in range(-10000000, 10000000)};' -n 1 '[k for k, v in d.items() if v > 6]' 
1 loops, best of 3: 2.47 sec per loop 
+0

+1。恕我直言,這絕對是最好的答案。 –

+5

對於python 2.x,'d.iteritems()'會更好AFAIK。 – hochl

+0

輝煌,謝謝! – Hoops

4

如何:

dictionary = {"foo":12, "bar":2, "jim":4, "bob": 17} 
for val in dictionary.values(): 
    # do something 
+0

如果OP不介意,我想刪除我的答案。 @ jamylak的這絕對是要走的路。 –

36

先手值,請使用dictionary.values()

要獲取鍵值對,使用dictionary.items()

10

字典上使用itemsiteritems。例如:

list = [] 
for k, v in dictionary.iteritems(): 
    if v > 6: 
    list.append(k) 
print list 
2

這取決於您是否要修改字典(添加或刪除項目)或不。如果沒有,那麼你可以嘗試:

for value in dictionary.itervalues(): #this returns a generator 
    print "do something with the value" 

或者,如果你修改了字典,你應該遍歷值的副本:

for value in dictionary.values(): #this returns a list of values 
    print "do something with the value" 

如果你想這兩個鍵和值,你可以使用在對迭代dictionary.iteritems()dictionary.items()

2

我認爲要做到這一點(在考慮遷移到Python 3)最好的辦法是

>>> mydict = {'foo': 12, 'bar': 2, 'jim': 4, 'bob': 17} 
>>> [k for k in mydict if mydict[k] > 6] 
['bob', 'foo'] 

「最好」的標準是可讀性。

(免責聲明:我的答案是總部設在亞歷馬爾泰利的答案,其他問題https://stackoverflow.com/a/3744713/556413和@ jamylak的這個問題)