vd = {'A': [1,0,1], 'B':[-1,0,1], 'C':[0,1,1]}
我想明智添加的列表元素的字典中添加元素。所以我想从列表A中添加第一个元素到列表B的第一个元素,反之亦然 复杂性在于你不能依赖于标签是A,B,C。它可以是任何东西。第二,字典的长度也是可变的。这里是3,但它可能是30
结果我需要的是一个列表[0,1,3]
vd = {'A': [1,0,1], 'B':[-1,0,1], 'C':[0,1,1]}
我想明智添加的列表元素的字典中添加元素。所以我想从列表A中添加第一个元素到列表B的第一个元素,反之亦然 复杂性在于你不能依赖于标签是A,B,C。它可以是任何东西。第二,字典的长度也是可变的。这里是3,但它可能是30
结果我需要的是一个列表[0,1,3]
简而言之:
>>> 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))
然后,只需更换sum
与average
:
>>> map(average, zip(*vd.values()))
[0.0, 0.3333, 1.0]
所以你只是想添加的所有值的elementwise?
[sum(l) for l in zip(*vd.values())]
我想这没有*。所以魔术是这个*在zip() – MySchizoBuddy
+1比我们接受的奇怪的地图解决方案更清晰 – wim
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)
我会带领解决方案,然后解释它。 – dansalmo
你能不能找到平均值? – MySchizoBuddy
@MySchizoBuddy:当然!我会将其添加到我的答案;等一下。 – icktoofay