5

With a list like this:

[1,1,1,2,2,3,3,3]

I would like to get the sums of each unique number [1,2,3] which is [3, 4, 9]. Using an approach from the related post How to get unique values with respective occurrence count from a list in Python? I'm able to get the count of the occurence of each uniqe number using:

L = [1,1,1,2,2,3,3,3]
uniq, counts = np.unique(L, return_counts=True)
counts

Which gives the output [3, 2, 3]. With this, I'm able to get what I'm looking for using a cumbersome approach with an enumerated For Loop and some rather cryptic conditions:

L = [1,1,1,2,2,3,3,3]
elements = [3,2,3]
    
sums = []
index = 0
for i, e in enumerate(elements):
    if i == 0:
        sums.append(sum(L[0:e]))
        index = index + e
    else:
        sums.append(sum(L[index:index + e]))
        index = index + e
print(sums)

Which gives the desired output [3, 4, 9]. Does anyone know if it's possible to do the same thing a bit more elegantly?

Star
  • 131
  • 3
  • 18
vestland
  • 55,229
  • 37
  • 187
  • 305

4 Answers4

6

Since you are using Numpy, you can just multiply the results you already have from np.unique:

import numpy as np

L = [1,1,1,2,2,3,3,3]    
uniq, counts = np.unique(L, return_counts=True)

uniq * counts
# array([3, 4, 9])
Mark
  • 90,562
  • 7
  • 108
  • 148
  • An old saying about a forest and some trees comes to mind... I really should have seen this.... – vestland May 03 '21 at 21:39
  • To my defense, my real world issue is a combination of lists of strings and lists of numbers. My minimal example in the question should really have reflected that too, – vestland May 03 '21 at 21:57
  • @vestland yeah, that would make a solution a little less concise for sure. – Mark May 03 '21 at 21:59
  • 1
    But your approach is very likely the most concise answer to my question as it stands, so I'll gladly mark it as the accepted answer and try again later with a more precise description of my real world challenge. – vestland May 03 '21 at 22:09
1

This solution assumes that the unique numbers are already grouped together:

from itertools import groupby

numbers = [1, 1, 1, 2, 2, 3, 3, 3]

print([sum(group) for _, group in groupby(numbers)])

Output:

[3, 4, 9]
>>> 
Paul M.
  • 10,481
  • 2
  • 9
  • 15
1

You can use collections.Couter() :

from collections import Counter

>>>L = [1,1,1,2,2,3,3,3]
>>>[k*v for k,v in Counter(L).items()]
[3, 4, 9]

or in a dict:

>>>{k:k*v for k,v in Counter(L).items()}
{1: 3, 2: 4, 3: 9}
zoldxk
  • 2,632
  • 1
  • 7
  • 29
1

You can do something like this using defaultdict or a dict

Using defaultdict:

from collections import defaultdict

a = [1, 1, 1, 2, 2, 3, 3, 3]
out = defaultdict(int)

for k in a :
    out[k] += k

print(list(out.values()))
# [3, 4, 9]

Using dict:

a = [1, 1, 1, 2, 2, 3, 3, 3]
out = {}

for k in a:
    if k in out:
        out[k] += k
    else:
        out[k] = k

print(list(out.values()))
# [3, 4, 9]
Chiheb Nexus
  • 9,104
  • 4
  • 30
  • 43