MySchizoBuddy
MySchizoBuddy

Reputation: 1156

How to add elements from a dictonary of lists in python

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

Answers (3)

rnbguy
rnbguy

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

icktoofay
icktoofay

Reputation: 129001

In short:

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

Explanation

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]

Extending to an average rather than a sum

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

nneonneo
nneonneo

Reputation: 179392

So you just want to add up all the values elementwise?

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

Upvotes: 9

Related Questions