2013-07-21 34 views
2

給出列表如何從列表的dictonary在python

vd = {'A': [1,0,1], 'B':[-1,0,1], 'C':[0,1,1]} 

我想明智添加的列表元素的字典中添加元素。所以我想從列表A中添加第一個元素到列表B的第一個元素,反之亦然 複雜性在於你不能依賴於標籤是A,B,C。它可以是任何東西。第二,字典的長度也是可變的。這裏是3,但它可能是30

結果我需要的是一個列表[0,1,3]

回答

4

簡而言之:

>>> map(sum, zip(*vd.values())) 
[0, 1, 3] 

說明

給出一個詞典:

>>> vd = {'A': [1,0,1], 'B': [-1,0,1], 'C': [0,1,1]} 

我們可以get the values

>>> values = vd.values() 
>>> values 
[[1, 0, 1], [-1, 0, 1], [0, 1, 1]] 

然後zip起來:

>>> zipped = zip(*values) 
>>> zipped 
[(1, -1, 0), (0, 0, 1), (1, 1, 1)] 

注意zip拉鍊了每個參數;它不會列出要壓縮的東西。因此,我們需要*將列表解壓縮爲參數。

如果我們只有一個列表,我們可以sum他們:

>>> sum([1, 2, 3]) 
6 

但是,我們有多個,所以我們在它可以map

>>> map(sum, zipped) 
[0, 1, 3] 

一起:

>>> map(sum, zip(*vd.values())) 
[0, 1, 3] 

擴展到平均值而非總和

這種方法也很容易擴展;例如,我們可以很容易地將它們的平均值而不是總和它們。要做到這一點,我們會先建立一個average功能:

def average(numbers): 
    # We have to do the float(...) so it doesn't do an integer division. 
    # In Python 3, it is not necessary. 
    return sum(numbers)/float(len(numbers)) 

然後,只需更換sumaverage

>>> map(average, zip(*vd.values())) 
[0.0, 0.3333, 1.0] 
+0

我會帶領解決方案,然後解釋它。 – dansalmo

+0

你能不能找到平均值? – MySchizoBuddy

+0

@MySchizoBuddy:當然!我會將其添加到我的答案;等一下。 – icktoofay

9

所以你只是想添加的所有值的elementwise?

[sum(l) for l in zip(*vd.values())]

+0

我想這沒有*。所以魔術是這個*在zip() – MySchizoBuddy

+0

+1比我們接受的奇怪的地圖解決方案更清晰 – wim

1
vd = {'A': [1,0,1], 'B':[-1,0,1], 'C':[0,1,1]} 
vd_keys = list(vd.keys()) 
rt = vd[vd_keys.pop()].copy() # copy otherwise rt and vd[vd_keys.pop()] will get synced 
for k in vd_keys: 
    for i in range(len(rt)): 
     rt[i] += vd[k][i] 

print(rt) 
+1

另一個(更詳細的)好的解決方案。你可能想補充說它會修改第一個元素,而我和nneonneo的解決方案不會。 – icktoofay

+0

@icktoofay哦!編輯我的代碼,以便它不會更改'vd'。 – rnbcoder