Reputation: 101
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
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
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
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