user3641829
user3641829

Reputation: 261

Summing up elements from one list based on indices in another list

So here is what I am trying to achieve in Python:

Example:

A = [0, 1, 0, 3, 2, 1, 2]  # (indicates unsorted and repeated indices)
B = [25, 10, 15, 10, 5, 30, 50]  # (values to be summed)
C = [25+15, 10+30, 5+50, 15]  # (summed values in a sorted manner)

So far I know how to do the sorting bit with:

C = zip(*sorted(zip(A, B)))

Getting the result:

[(0, 0, 1, 1, 2, 2, 3), (15, 25, 10, 30, 5, 50, 10)] 

But I do not know how to do the sum.

What would be a good way to create list C?

Upvotes: 0

Views: 1228

Answers (3)

It is actually a bit unclear what you want, but if you want them to be indexed by whatever the number is, you shouldn't even use a list, but a Counter instead:

>>> from collections import Counter
>>> c = Counter()
>>> A = [0, 1, 0, 3, 2, 1, 2]
>>> B = [25, 10, 15, 10 , 5, 30, 50]
>>> for k, v in zip(A, B):
...     c[k] += v
...
>>> c
Counter({2: 55, 0: 40, 1: 40, 3: 10})
>>> c[0]
40

If you really want a list, you can use

>>> [i[1] for i in sorted(c.items())]

but then any missing key would cause the rest of the values show up upper, which might or might not be that what you wanted.

Upvotes: 0

Ilja Everilä
Ilja Everilä

Reputation: 52939

You could use groupby, if the order matters:

In [1]: A=[0 , 1 , 0 , 3 , 2 , 1 , 2]

In [2]: B=[25 , 10 , 15 , 10 , 5 , 30 , 50]

In [3]: from itertools import groupby

In [4]: from operator import itemgetter

In [5]: C = [sum(map(itemgetter(1), group))
   ...:      for key, group in groupby(sorted(zip(A, B)),
   ...:                                key=itemgetter(0))]

In [6]: C
Out[6]: [40, 40, 55, 10]

or defaultdict(float), if it does not:

In [10]: from collections import defaultdict

In [11]: res = defaultdict(float)

In [12]: for k, v in zip(A, B):
    ...:     res[k] += v
    ...:     

In [13]: res
Out[13]: defaultdict(float, {0: 40.0, 1: 40.0, 2: 55.0, 3: 10.0})

Note that dicts in python are unordered (you are not to trust any CPython implementation details).

Upvotes: 0

Jan
Jan

Reputation: 43169

Use zip() in combination with a dict:

A = [0 , 1 , 0 , 3 , 2 , 1 , 2] 
B = [25 , 10 , 15 , 10 , 5 , 30 , 50]

sums = {}
for key, value in zip(A,B):
    try:
        sums[key] += value
    except KeyError:
        sums[key] = value
print(sums)
# {0: 40, 1: 40, 2: 55, 3: 10}

And see a demo on ideone.com.

Upvotes: 4

Related Questions