2011-12-29 56 views
1

例如,Python的字典或替代

if dict['sample']: 
    //append values to dict['sample'] 
else: 
    // assign new key to the python dictionary 

如果字典[ '樣品']是空的,Python會引發錯誤。有誰知道一個更好的方法來檢查這個?我想要的是類似的東西,我會有數據列表,比如說a,a,b,c,g,g,g,g,g。

所以,我想要python字典追加兩個a,a到dict ['a']和g,g,g,g到dict ['g']的值,剩下的就像字典['b']等等.for循環將被執行以循環通過a,a,b,c,g,g,g,g,g的數據。

我希望我已經明確了我的問題。任何想法?最好,如果Python的字典有辦法檢查現有的密鑰。

編輯

幸得@保羅麥圭爾。基於@Paul McGuire的回答,我已經想出了我想要的確切解決方案。如下圖所示:

from collections import defaultdict 

class Test: 
    def __init__(self, a,b): 
     self.a=a 
     self.b=b 

data = [] 
data.append(Test(a=4,b=6)) 
data.append(Test(a=1,b=2)) 
data.append(Test(a=1,b=3)) 
data.append(Test(a=2,b=2)) 
data.append(Test(a=3,b=2)) 
data.append(Test(a=4,b=5)) 
data.append(Test(a=4,b=2)) 
data.append(Test(a=1,b=2)) 
data.append(Test(a=5,b=9)) 
data.append(Test(a=4,b=7)) 

dd = defaultdict(list) 
for c in data: 
    dd[c.a].append(c.b) 
print dd 
+0

另一個學習的機會 - * namedtuple *。替換你的Test類(它應該擴展'object',BTW),用下面的代碼:'Test = namedtuple(「Test」,「ab」)',將'namedtuple'加入你從彙集模塊導入的內容, 。 'namedtuples'對於這些簡單的類結構類很方便,並且它們是不可變的,因此可以用作適當的字典鍵和設置值。 – PaulMcG 2011-12-30 16:39:41

+0

再次感謝您的知識。以上只是我寫的一個例子。我應該從服務器端獲取數據並返回GQL查詢對象。但是你的建議肯定有助於未來的需求。再次感謝 ! :) – MrCooL 2011-12-30 18:37:13

回答

13

「如果鍵入字典」或「dict.get」或「字典」的舊方法。setdefault」都應該贊成現在的標準defaultdict的被擱置:

data = "aabcggggg" 

from collections import defaultdict 
dd = defaultdict(list) 
for c in data: 
    dd[c].append(c) 
print dd 

defaultdict需要重點生存的檢查你的關心,你的所有代碼所要做的就是1)定義了一個工廠函數或類用於初始化新密鑰條目(在本例中爲defaultdict(list))的defaultdict,以及2)定義如何處理每個密鑰(dd[c].append(c))。實際上使用itertools.groupby,因爲字母組對於每個分組值都是連續的。groupby返回元組的迭代器,每個元組都包含一個元組包含當前鍵值和匹配值的迭代器。以下代碼通過將每個元組的列表值迭代器轉換爲實際列表(在list(v)中)並將鍵值列表元素的序列傳遞給字典構造函數來工作。

from itertools import groupby 
print dict((k,list(v)) for k,v in groupby(data)) 

打印:

{'a': ['a', 'a'], 'c': ['c'], 'b': ['b'], 'g': ['g', 'g', 'g', 'g', 'g']} 
+0

非常感謝@Paul McGuire,我沒有詳細描述我正在寫的代碼。我將其歸納爲上面的問題。實際上,我將循環使用對象而不僅僅是字母。 但是,您的答案仍然爲許多人提供額外的知識。非常感謝!非常感謝 ! ;) – MrCooL 2011-12-29 14:11:37

+0

順便說一句@Paul McGuire,我只是想知道你和'if key in dict'之間有什麼重大區別?因爲對於我的情況,一旦檢測到相同的密鑰,我需要執行不同的操作。 如果這對更好的性能有影響,我想接受您的答案。但是,我只是想知道它是否解決了我的問題。我編輯了我的問題。 – MrCooL 2011-12-30 07:46:20

+0

Hi @Paul McGuire,我已經接受你的答案,因爲我發佈了最適合我要解決的問題的最新解決方案。 我已經在我的問題上發佈了確切的解決方案。 :) 但是,我仍然希望你能解釋你與他人之間有點顯著差異,你已經從你的第一個聲明「強調的老辦法:‘如果在字典鍵’或‘dict.get’或「字典。 setdefault」都應該拋開贊成現在的標準defaultdict」 – MrCooL 2011-12-30 08:20:31

2

每個dict鍵都應該包含一個列表。我對嗎?

d = dict() 
try: 
    d['sample'].append(new_data) 
except KeyError: 
    d['sample'] = [new_data] 

我相信這會奏效。順便說一句,你不應該使用dictonary的名字字典。字典已被用作函數。

編輯1:

我不太確定我明白你想要做什麼。我也不知道我的解決方案是否是最好的解決方案。但是你試圖這樣做嗎?這似乎有點奇怪?或者你想要統計每個字母出現多少次?

# Create a list named l. 
l = ['a', 'a', 'b', 'c', 'g', 'g', 'g', 'g','g'] 

# Create dictionary named d. 
d = dict() 

for i in l: 
    try: 
     d[i].append(i) 
    except KeyError: 
     d[i] = [i] 
+0

沒關係。我想我錯過了你的問題。 – 2011-12-29 11:47:57

+0

@Niclas Nilsson雖然沒有直接解決我的問題,但它幫助我找出了除KeyError之外的解決方案:它幫助了很多@Niclas Nilsson:。我明顯忽略了這一點。非常感謝 ! – MrCooL 2011-12-29 13:22:56

5
my_dict = {} 
my_dict.setdefault('sample', []).append(value) 

「setdefault」方法的第二個參數說的話應該是初始值,如果給定的鍵不存在

4

如果我理解你的價值觀是列表。

if 'sample' in mydict: 
    pass #whatever 
else: 
    mydict['sample'] = [] 

你想要做的是以下幾點:

A = ['a','a','b','b','b','c','c','c'] 

myDict = {} 
for i in A: 
    if i not in myDict: 
     myDict[i] = [] 
    myDict[i].append(i) 
print myDict 
+0

這也適用。我已經發布了我自己的答案,關於我認爲我想要的最簡單的解決方案。但是,決定把功勞歸功於你,因爲它的工作方式也很好。謝謝 ! – MrCooL 2011-12-29 13:30:21

+0

我明白爲什麼人們投了我的答案:即使是一個新手(像我一樣)通過閱讀我簡單的代碼來理解發生了什麼。但是,在閱讀這個問題的其他答案時,我瞭解到了defaultdict!事實上,如果我明白了,它就像字典的子類一樣,我已經重載了成員函數來獲取一個試圖獲取項目的項目(除了默認值)。 如果您僅將字典用作列表字典(並且這是您在整個程序中期望的行爲),我的解決方案是無意義的(因爲它需要大量的代碼複製粘貼),並且解決方案是defaultdict! – jimifiki 2011-12-29 13:44:27

+0

我確實相信一個「如果」的陳述更美觀,然後使用例外,就像我只是出於習慣。只是想告訴:) – 2011-12-29 13:52:23

0

如果您使用的是一些很老的Python:

if not myDict.has_key(key): 
    myDict[key]=[val] 
else: 
    myDict[key].append(val) 

最近對象的has_key一直贊成key in dict 棄用所以現在,它應該是:

if not key in myDict: 
    myDict[key]=[val] 
else: 
    myDict[key].append(val) 
+0

不要延續這種做法! has_key在許多版本之前被棄用,主張「if key in myDict:」。最近有沒有 – PaulMcG 2011-12-29 11:52:27

+0

?可能沒有太多人使用Python 2.1或更高版本 – 2011-12-29 13:41:06

+0

同意,但在我的防守中,OP從未提及過哪個版本的python。 – 2011-12-29 18:22:12

0

信貸應該去@Niclas尼爾森儘管他發佈的解決方案並沒有真正工作了我想要的東西,但是它沒有幫我找出瞭解決方案,我想要最簡單的形式。

不過,我很感謝大家在這裏獲得的額外知識和解決辦法。非常感謝。

繼實現我在最簡單的方法想無需額外的庫中導入等:

r = {} 

try: 
    if r['new_data']: 
     r['new_data'] = 'appending' 
except KeyError: 
    r['new_data'] = 'new value' 

print r['new_data'] 
+0

高興它爲你工作... – 2011-12-29 13:23:02

+0

再次感謝豬頭非常感謝您的幫助保持良好的工作;。!) – MrCooL 2011-12-29 13:34:19

0

確切的解決方案,我想最如下圖所示。信貸去@Paul McGuire

from collections import defaultdict 

class Test: 
    def __init__(self, a,b): 
     self.a=a 
     self.b=b 

data = [] 
data.append(Test(a=4,b=6)) 
data.append(Test(a=1,b=2)) 
data.append(Test(a=1,b=3)) 
data.append(Test(a=2,b=2)) 
data.append(Test(a=3,b=2)) 
data.append(Test(a=4,b=5)) 
data.append(Test(a=4,b=2)) 
data.append(Test(a=1,b=2)) 
data.append(Test(a=5,b=9)) 
data.append(Test(a=4,b=7)) 

dd = defaultdict(list) 
for c in data: 
    dd[c.a].append(c.b) 
print dd