user3309069
user3309069

Reputation: 101

How to get a frequency of the elements in python?

I am new to python and struggling a little in manipulating lists. I have a list which roughly looks like this

rows = [[u'12'], [u'12'], [u'12'], [u'12'], [u'13'], [u'13'], [u'14'], [u'14'], [u'14']]

. I want to get the count of each of these elements. I would like the result to look like this

res = [[12,4], [13,2], [14,3]]

How do I do this? I tried

collections.Counter(rows)

but it gave me

TypeError: Unhashable type 'list'

Upvotes: 2

Views: 87

Answers (3)

Stepan Grigoryan
Stepan Grigoryan

Reputation: 3162

The reason you get the error TypeError: Unhashable type 'list' is because you are trying to make the list as the key for the dictionary which is not allowed because list is a mutable object. Mutable objects are not allowed to be keys since they can change. You have couple of options for your issue above. Either you can turn your list into a tuple which is immutable object or since it looks like your lists contain just one element, you can just get the first element. Here is an implementation of that below:

rows = [[u'12'], [u'12'], [u'12'], [u'12'], [u'13'], [u'13'], [u'14'], [u'14'], [u'14']]
count_dict = {}
for row in rows:
    key = row[0]
    if key in count_dict:
        count_dict[key] += 1
    else:
        count_dict[key] = 1 

print count_dict

That will get you {u'13': 2, u'12': 4, u'14': 3}

Upvotes: 0

thefourtheye
thefourtheye

Reputation: 239443

collections.Counter is the way to go. But you are actually passing the list of lists as it is. You actually need to flatten the list of lists and then pass it to Counter.

rows = [[u'12'],[u'12'],[u'12'],[u'12'],[u'13'],[u'13'],[u'14'],[u'14'],[u'14']]
from itertools import chain
from collections import Counter
res = sorted(Counter(int(item) for item in chain.from_iterable(rows)).items())
print res

Output

[(12, 4), (13, 2), (14, 3)]

Upvotes: 0

John La Rooy
John La Rooy

Reputation: 304137

Do the sublists always have just one item?

>>> rows = [[u'12'],[u'12'],[u'12'],[u'12'],[u'13'],[u'13'],[u'14'],[u'14'],[u'14']]
>>> from collections import Counter
>>> [[int(k), v] for k, v in Counter(i[0] for i in rows).items()]
[[13, 2], [12, 4], [14, 3]]

If the sublists can have more than one item

>>> [[int(k), v] for k, v in Counter(j for i in rows for j in i).items()]
[[13, 2], [12, 4], [14, 3]]

You can throw sorted into the mix like this, if the order is important

>>> sorted([int(k), v] for k, v in Counter(i[0] for i in rows).items())
[[12, 4], [13, 2], [14, 3]]

Upvotes: 2

Related Questions