Reputation: 1156
given a dictionary of lists
vd = {'A': [1,0,1], 'B':[-1,0,1], 'C':[0,1,1]}
I want to add the lists element wise. So I want to add first element from list A to first element of list B vice versa the complexity is that you cannot rely on the labels being A, B, C. It can be anything. second the length of the dictionary is also variable. here it is 3. but it could be 30.
The result i need is a list [0, 1, 3]
Upvotes: 2
Views: 155
Reputation: 1399
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)
Upvotes: 1
Reputation: 129001
In short:
>>> map(sum, zip(*vd.values()))
[0, 1, 3]
Given a dictionary:
>>> vd = {'A': [1,0,1], 'B': [-1,0,1], 'C': [0,1,1]}
We can get the values:
>>> values = vd.values()
>>> values
[[1, 0, 1], [-1, 0, 1], [0, 1, 1]]
Then zip them up:
>>> zipped = zip(*values)
>>> zipped
[(1, -1, 0), (0, 0, 1), (1, 1, 1)]
Note that zip
zips up each argument; it doesn't take a list of things to zip up. Therefore, we need the *
to unpack the list into arguments.
If we had just one list, we could sum them:
>>> sum([1, 2, 3])
6
However, we have multiple, so we can map over it:
>>> map(sum, zipped)
[0, 1, 3]
All together:
>>> map(sum, zip(*vd.values()))
[0, 1, 3]
This approach is also easily extensible; for example, we could quite easily make it average the elements rather than sum them. To do that, we'd first make an average
function:
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))
Then just replace sum
with average
:
>>> map(average, zip(*vd.values()))
[0.0, 0.3333, 1.0]
Upvotes: 4
Reputation: 179392
So you just want to add up all the values elementwise?
[sum(l) for l in zip(*vd.values())]
Upvotes: 9