2009-01-23 54 views
212

給定一個字典,我該如何確定該字典中給定的密鑰是否已經設置爲非無值?檢查一個給定的密鑰是否已經存在於一個字典中並增加它

即,我想這樣做:

my_dict = {} 

if (my_dict[key] != None): 
    my_dict[key] = 1 
else: 
    my_dict[key] += 1 

即,我要增加值,如果有一個已經存在,或將其設置爲1,否則。

+5

小碼雞蛋裏挑骨頭:代碼設置my_dict [關鍵] 1,如果有已經存在的東西,並增加它,如果不存在。我想你想==,不!!=。 – QuantumFool 2016-06-23 17:20:58

回答

242

您正在尋找collections.defaultdict(適用於Python 2.5+)。這

from collections import defaultdict 

my_dict = defaultdict(int) 
my_dict[key] += 1 

會做你想做的。

對於常規的Python dict S,如果沒有價值給定的鍵,你會不會訪問的字典時獲得None - 一個KeyError將提高。所以,如果你想使用一個普通dict,而不是你的代碼,你會使用

if key in my_dict: 
    my_dict[key] += 1 
else: 
    my_dict[key] = 1 
+7

根據他的例子,設置「defaultdict(lambda:0)」並跳過整個「if」子句應該足夠了。 – Deestan 2009-01-23 14:57:21

+0

這有效,但會混淆鍵和值(使其閱讀有點奇怪)。 'some_value'應該是'some_key' – mikemaccana 2009-11-17 11:42:52

+0

@nailer:固定,謝謝。我最初使用'some_value',因爲這是問題中的變量名稱,但我同意現在更清楚。 – 2009-11-18 01:11:45

44

您需要key in dict成語了點。

if key in my_dict and not (my_dict[key] is None): 
    # do something 
else: 
    # do something else 

但是,你應該考慮使用defaultdict(如DMF建議)。

+1

請注意,至少2。6 has_key()已被刪除以支持d中的鍵。我認爲這也是2.5。 – 2009-01-23 15:18:11

+0

請注意,可以寫`my_dict [key]不是無`,這是更清晰的(恕我直言,至少) – brandizzi 2012-07-26 17:02:43

+0

@brandizzi - 同意,如果鍵在my_dict和my_dict [key]:` – 2017-09-08 10:52:24

4

您試圖做到這一點的方式稱爲LBYL(在您跳躍之前查看),因爲您在嘗試增加值之前檢查條件。

另一種方法被稱爲EAFP(更容易請求原諒,然後權限)。在這種情況下,您只需嘗試操作(增加值)。如果失敗,則會捕獲異常並將值設置爲1.這是一種稍微更加Pythonic的方式(IMO)。

http://mail.python.org/pipermail/python-list/2003-May/205182.html

9

同意cgoldberg。我如何做到這一點是:

try: 
    dict[key] += 1 
except KeyError: 
    dict[key] = 1 

因此,無論做如上,或使用默認的字典正如其他人建議。不要使用if語句。這不是Pythonic。

+5

如果if語句不是Pythonic? – 2011-11-08 21:20:18

+1

我認爲這是Python的EAFP不是最好的方法。上面的示例具有重複的代碼;如果有一天我們想要`+ = 2`或` - = 1`?你必須記住改變兩條線。它現在看起來可能是一件小事,但那些愚蠢的「微不足道」的錯誤可能會反過來咬你。 – 2012-01-04 02:33:02

207

我寧願在一行代碼中這樣做。

 
my_dict = {} 

my_dict[some_key] = my_dict.get(some_key, 0) + 1 

字典有一個函數,拿,這需要兩個參數 - 您想要的關鍵,如果它不存在默認值。我更喜歡這種方法,因爲你只想處理在這一行代碼中不存在密鑰的情況,而不是到處都是。

10

正如您從許多答案中可以看到的,有幾種解決方案。LBYL(三思而後行)的一個實例尚未提到的,對象的has_key()方法:

my_dict = {} 

def add (key): 
    if my_dict.has_key(key): 
     my_dict[key] += 1 
    else: 
     my_dict[key] = 1 

if __name__ == '__main__': 
    add("foo") 
    add("bar") 
    add("foo") 
    print my_dict 
12

要回答這個問題:「我怎麼能發現如果在字典給定的指數已是設置非無值」,我寧願這樣:

try: 
    nonNone = my_dict[key] is not None 
except KeyError: 
    nonNone = False 

這符合EAFP的已經調用概念(更容易請求原諒,然後權限)。它還避免了字典中的重複密鑰查找,就像在key in my_dict and my_dict[key] is not None中那樣,如果查找代價昂貴,那麼有趣的是什麼。

對於實際問題你已經提出,即增加一個int如果它存在,否則將其設置爲默認值,我也建議

my_dict[key] = my_dict.get(key, default) + 1 

在安德魯·威爾金森的答案。

如果您在字典中存儲可修改對象,還有第三種解決方案。一個常見的例子是multimap,其中存儲了您的密鑰的元素列表。在這種情況下,你可以使用:

my_dict.setdefault(key, []).append(item) 

如果key值不存在於字典中,setDefault方法將其設置爲setdefault的第二個參數。它的行爲就像一個標準的my_dict [key],返回鍵的值(可能是新設置的值)。

0

我一直在尋找它,並沒有發現它的網絡,然後想我的運氣嘗試/錯誤,並發現它

my_dict = {} 

if my_dict.__contains__(some_key): 
    my_dict[some_key] += 1 
else: 
    my_dict[some_key] = 1 
30

我個人比較喜歡使用setdefault()

my_dict = {} 

my_dict.setdefault(some_key, 0) 
my_dict[some_key] += 1 
2

這裏的單我最近想出來解決這個問題。它基於setdefault字典方法:

my_dict = {} 
my_dict[key] = my_dict.setdefault(key, 0) + 1 
4

有點晚,但這應該工作。

my_dict = {} 
my_dict[key] = my_dict[key] + 1 if key in my_dict else 1 
2

這不是直接回答這個問題,但對我來說,它看起來像你可能想的collections.Counter功能。

from collections import Counter 

to_count = ["foo", "foo", "bar", "baz", "foo", "bar"] 

count = Counter(to_count) 

print(count) 

print("acts just like the desired dictionary:") 
print("bar occurs {} times".format(count["bar"])) 

print("any item that does not occur in the list is set to 0:") 
print("dog occurs {} times".format(count["dog"])) 

print("can iterate over items from most frequent to least:") 
for item, times in count.most_common(): 
    print("{} occurs {} times".format(item, times)) 

這將導致輸出

Counter({'foo': 3, 'bar': 2, 'baz': 1}) 
acts just like the desired dictionary: 
bar occurs 2 times 
any item that does not occur in the list is set to 0: 
dog occurs 0 times 
can iterate over items from most frequent to least: 
foo occurs 3 times 
bar occurs 2 times 
baz occurs 1 times 
相關問題