2012-06-29 31 views
2

我的數據是製表符分隔的,看起來像這樣:在Python中,我如何找到字典中的值的總和?其中每個鍵有多個值

Name Count Sample 
Dog .0001 1 
Dog .00003 1 
Dog .0001 2 
Cat .0004 1 
Cat .0002 1 
Cat .0003 2 
Cat .0002 2 

後,我確定我的變量UNID作爲第一列與第3列(前Dog_1)和num作爲計數的合併該行,我追加各NUM到字典中的UNID下(使用Python 2.7),像這樣:

for line in K: 
     sp = line.split("\t") 
     name = sp[0] 
     unid = sp[3][:-2] +"_"+ sp[0] 
     num = int(Decimal(sp[1])) 
     if not dict1.has_key(unid): 
      dict1[unid] = [] 
     dict1[unid].append(num) 

我嘗試與此來概括:

dictTot = sum(dict1.values()) 

但我收到此錯誤信息:

TypeError: unsupported operand type(s) for +: 'int' and 'list' 

我如何總結這些值,這樣我可以取回​​等?

對不起,大家好,我知道我的嗎?不是很好。但正如Jacob所述, 「dictTot = sum(sum(value)for dict1.values())」將所有的總和相加,但我正在尋找的是將每個鍵下的每組值相加所以我可以找出樣本1中有多少隻貓,等等。也許總和是不正確的呢?對不起,很明顯,我不是一個非常優秀的Python。

+0

你能提供的字典,即內容,如果你打印你會得到什麼'dict1' – Levon

+3

''INT爲0。您的所有樣本值將爲0. –

+0

'sp [3]'超出索引。 –

回答

1

我基本上重寫了整個事情...

K = "Dog .0001 1\n Dog .00003 1\n Dog .0001 2\n Cat .0004 1\n Cat .0002 1\n Cat .0003 2\n Cat .0002 2" 
dict1 = {} 
for line in K.split("\n"): 
    sp = line.split() 
    name = sp[0] 
    unid = "_".join([sp[0] , sp[2][-2:]]) 
    num = float(sp[1]) 
    if not dict1.has_key(unid): 
     dict1[unid] = [num,] 
    else : 
     dict1[unid].append(num) 
print(dict1) 
dictTot = sum([sum(x) for x in dict1.values()]) 
print(dictTot) 

最終的字典是

{'Dog_2': [0.0001], 
'Dog_1': [0.0001, 3e-05], 
'Cat_1': [0.0004, 0.0002], 
'Cat_2': [0.0003, 0.0002]} 

總和

0.00133 

值爲l ists,所以你想循環他們來單獨總結。

編輯

顯然現在你想「Cat_1:0.0006,Cat_2:。0005等」,所以在dict1,你可以做

for key in dict1.iterkeys(): 
    dict1[key] = sum(dict1[key]) 

現在dict1成爲

{'Dog_2': 0.0001, 
'Dog_1': 0.00013, 
'Cat_1': 0.0006, 
'Cat_2': 0.0005} 
+1

這是'defaultdict' –

+0

的完美使用案例!哇感謝您通過無意間放置的霧看到 – Vince

+0

@Vince哈哈,我喜歡你的描述,很高興霧不像我窗外的雷雨那麼濃。 ;-) – nye17

2

這不是sum的工作方式。你試圖通過「添加」一堆列表來獲得一個整數(或數值類型),所以內置函數會嚇倒。試試這個:

dictTot = sum(sum(value) for value in dict1.values()) 

這將總結所有的總和,這是你想要的(我認爲)。

編輯

顯然要總結列表中的每個元素都值。爲了這個目的,你可以使用一個dictionary comprehension

dictTot = {key:sum(l_values) for key, l_values in dict1.items()} 
+0

對不起,我知道我的?並不好。但正如雅各布所說,「dictTot = sum(dict1.values()中的值的總和(值))」將所有的總和相加,但我所尋找的是獨立地求和每組值,所以我可以找出樣本1中有多少貓,等等。 – Vince

+0

@Vince請看我編輯的答案。 – nye17

1

爲了總結所有的值,你必須先加入所有列表連成一個迭代是sum()能。過程這裏有兩種方法可以做到這一點:

dictTot = sum(sum(dict1.values(), [])) 

而且稍微詳細,但更可讀的:

from itertools import chain 
dictTot = sum(chain.from_iterable(dict1.values())) 

sum()實際上有兩個參數。第二個參數start默認爲0。因此,您收到有關將int添加到list的錯誤消息。實質上,它是這樣做的:0 + [1, 2, 3] + [1, 2]...。在我的第一個例子中,我將默認開始值設置爲空列表。結果是一個單一的列表。現在,我已將所有值都列在一個列表中,我可以用sum()結果來獲得答案。

編輯

在回答您的更新:

您可以用生成器表達式做到這一點:

dictTot = {key: sum(value) for key, value in dictTot.items()} 

,或者如果你正在使用<的Python 2.7:

dictTot = dict((key, sum(value)) for key, value in dictTot.iteritems()) 
0

答案:

dict((k,sum(v)) for k,v in dict1.iteritems())

啊,改變int(Decimal('.0001'))和使用defaultdict

+1與downvotes一個問題,然後四個答案是錯過了oneliner答案

編輯哎呀我錯過了@ Joel Cornett也有這樣的道具

0

這個作品:

d={} 
for line in K: 
    sp = line.strip().split() 
    unid = sp[0]+"_"+sp[-1] 
    num = decimal.Decimal(sp[1]) 
    d.setdefault(unid,[]).append(num)  

print({k:sum(v) for k, v in d.items()}) 

打印:(「0001' 十進制())

{'Dog_1': Decimal('0.00013'), 
'Cat_2': Decimal('0.0005'), 
'Cat_1': Decimal('0.0006'), 
'Dog_2': Decimal('0.0001')} 
相關問題