2013-07-21 29 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