3

I want to count the instances of X in a list, similar to

How can I count the occurrences of a list item in Python?

but taking into account a weight for each instance.

For example,

L = [(a,4), (a,1), (b,1), (b,1)]

the function weighted_count() should return something like

[(a,5), (b,2)]

Edited to add: my a, b will be integers.

Community
  • 1
  • 1
Admiral Tso
  • 71
  • 2
  • 7

6 Answers6

7

you can still use counter:

from collections import Counter
c = Counter()
for k,v in L:
    c.update({k:v})
print c
Fabricator
  • 12,722
  • 2
  • 27
  • 40
  • This does not seem to remember the ordering. For example, doing this for [(2, 1), (2, 2), (2, 1), (3, 1), (2, 1), (5, 1), (2, 2)] output Counter({1: 5, 2: 5, 3: 1, 5: 1}) – Admiral Tso Jan 08 '16 at 20:04
  • Thanks! Note also that c.update({k:1.5}) also seems to work (i.e. non-integral values are also allowed). – Geordie Williamson Jan 02 '23 at 21:06
1

The following will give you a dictionary of all the letters in the array and their corresponding counts

counts = {}
for value in L:
    if value[0] in counts:
        counts[value[0]] += value[1]
    else:
        counts[value[0]] = value[1]

Alternatively, if you're looking for a very specific value. You can filter the list for that value, then map the list to the weights and find the sum of them.

def countOf(x,L):
    filteredL = list(filter(lambda value: value[0] == x,L))
    return sum(list(map(lambda value: value[1], filteredL)))
mattsap
  • 3,790
  • 1
  • 15
  • 36
1
>>> import itertools
>>> L = [ ('a',4), ('a',1), ('b',1), ('b',1) ]
>>> [(k, sum(amt for _,amt in v)) for k,v in itertools.groupby(sorted(L), key=lambda tup: tup[0])]
[('a', 5), ('b', 2)]
Kevin
  • 74,910
  • 12
  • 133
  • 166
1

defaultdict will do:

from collections import defaultdict

L = [('a',4), ('a',1), ('b',1), ('b',1)]
res = defaultdict(int)
for k, v in L:
    res[k] += v
print(list(res.items()))

prints:

[('b', 2), ('a', 5)]
Mike Müller
  • 82,630
  • 20
  • 166
  • 161
1

Group items with the occurrence of first element of each tuple using groupby from itertools:

>>> from itertools import groupby
>>> from operator import itemgetter
>>> L = [('a',4), ('a',1), ('b',1), ('b',1)]
>>> L_new = []
>>> for k,v in groupby(L,key=itemgetter(0)):
    L_new.append((k,sum(map(itemgetter(1), v))))

>>> L_new
[('a', 5), ('b', 2)]
>>> L_new = [(k,sum(map(itemgetter(1), v))) for k,v in groupby(L, key=itemgetter(0))] #for those fun of list comprehension and one liner expression
>>> L_new
[('a', 5), ('b', 2)]

Tested in both Python2 & Python3

Iron Fist
  • 10,739
  • 2
  • 18
  • 34
0

Use the dictionaries get method.

>>> d = {}
>>> for item in L:
...     d[item[0]] = d.get(item[0], 0) + item[1]
... 
>>> d
{'a': 5, 'b': 2}
timgeb
  • 76,762
  • 20
  • 123
  • 145