Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: Counting occurrences of List element within List

Tags:

python

list

count

I'm trying to count the number of occurrences of elements within a list, if such elements are also lists. The order is also important.

[PSEUDOCODE]

lst = [ ['a', 'b', 'c'], ['d', 'e', 'f'], ['a', 'b', 'c'], ['c', 'b', 'a'] ]
print( count(lst) )


> { ['a', 'b', 'c'] : 2, ['d', 'e', 'f']: 1, ['c', 'b', 'a']: 1 }

One important factor is that ['a', 'b', 'c'] != ['c', 'b', 'a']

I have tried:

from collections import counter
print( Counter([tuple(x) for x in lst]) )
print( [[x, list.count(x)] for x in set(lst)] )

Which both resulted in ['a', 'b', 'c'] = ['c', 'b', 'a'], one thing i didn't want

I also tried:

from collections import counter
print( Counter( lst ) )

Which only resulted in error; since lists can't be used as keys in dicts.

Is there a way to do this?

like image 737
Olle Avatar asked Jan 01 '18 20:01

Olle


People also ask

How do you count how many times a value appears in a list?

Use the COUNTIF function to count how many times a particular value appears in a range of cells. For more information, see COUNTIF function.

How do you count the number of times a string appears in a list Python?

The Python count() method can be used to count the number of times a particular item appears in a list or a string. When used with a string, the count() method counts the number of times a substring appears in a larger string.


3 Answers

You can't have list as a key to the dict because dictionaries only allows immutable objects as it's key. Hence you need to firstly convert your objects to tuple. Then you may use collection.Counter to get the count of each tuple as:

>>> from collections import Counter
>>> my_list = [ ['a', 'b', 'c'], ['d', 'e', 'f'], ['a', 'b', 'c'], ['c', 'b', 'a'] ]

#            v to type-cast each sub-list to tuple
>>> Counter(tuple(item) for item in my_list)
Counter({('a', 'b', 'c'): 2, ('d', 'e', 'f'): 1, ('c', 'b', 'a'): 1})
like image 125
Moinuddin Quadri Avatar answered Nov 07 '22 15:11

Moinuddin Quadri


just use collections.Counter on some equivalent type but hashable: the tuple:

import collections

lst = [ ['a', 'b', 'c'], ['d', 'e', 'f'], ['a', 'b', 'c'], ['c', 'b', 'a'] ]

c = collections.Counter(tuple(x) for x in lst)

print(c)

result:

Counter({('a', 'b', 'c'): 2, ('d', 'e', 'f'): 1, ('c', 'b', 'a'): 1})
like image 34
Jean-François Fabre Avatar answered Nov 07 '22 14:11

Jean-François Fabre


Lists are not hashable, but you can use tuples as a workaround:

l = [ ['a', 'b', 'c'], ['d', 'e', 'f'], ['a', 'b', 'c'], ['c', 'b', 'a'] ]
new_l = list(map(tuple, l))
final_l = {a:new_l.count(a) for a in new_l}

Output:

{('a', 'b', 'c'): 2, ('d', 'e', 'f'): 1, ('c', 'b', 'a'): 1}

Or, if you really want to use lists, you can create a custom class to mimic the functionality of a dictionary hashing lists:

class List_Count:
    def __init__(self, data):
       new_data = list(map(tuple, data))
       self.__data = {i:new_data.count(i) for i in new_data}
    def __getitem__(self, val):
       newval = [b for a, b in self.__data.items() if list(a) == val]
       if not newval:
          raise KeyError("{} not found".format(val))
       return newval[0]
    def __repr__(self):
       return "{"+"{}".format(', '.join("{}:{}".format(list(a), b) for a, b in self.__data.items()))+"}"

l = List_Count([ ['a', 'b', 'c'], ['d', 'e', 'f'], ['a', 'b', 'c'], ['c', 'b', 'a'] ])
print(l)
print(l[['a', 'b', 'c']])

Output:

{['a', 'b', 'c']:2, ['d', 'e', 'f']:1, ['c', 'b', 'a']:1}
2
like image 45
Ajax1234 Avatar answered Nov 07 '22 15:11

Ajax1234