Reputation: 107
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?
Upvotes: 7
Views: 3927
Reputation:
Don't Use list as variable name.
You can try this approach if you don't want to use any module :
list_1 = [ ['a', 'b', 'c'], ['d', 'e', 'f'], ['a', 'b', 'c'], ['c', 'b', 'a'] ]
track={}
for i in list_1:
if tuple(i) not in track:
track[tuple(i)]=1
else:
track[tuple(i)]+=1
print(track)
outoput:
{('a', 'b', 'c'): 2, ('d', 'e', 'f'): 1, ('c', 'b', 'a'): 1}
You can also use default dict:
list_1 = [ ['a', 'b', 'c'], ['d', 'e', 'f'], ['a', 'b', 'c'], ['c', 'b', 'a'] ]
track={}
import collections
d=collections.defaultdict(list)
for j,i in enumerate(list_1):
d[tuple(i)].append(j)
print(list(map(lambda x:{x:len(d[x])},d.keys())))
Upvotes: 2
Reputation: 71451
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
Upvotes: 6
Reputation: 3510
Another implementation with lists
l1 = [["a", "b", "c"], ["b", "c", "d"], ["a", "b", "c"], ["c", "b", "a"]]
def unique(l1):
l2 = []
for element in l1:
if element not in l2:
l2.append(element)
return l2
l2 = unique(l1)
for element in l2:
print(element, l1.count(element))
and if you want an dictionary from that you can just change the last part to
output = {element:l1.count(element) for element in unique(l1)}
Upvotes: 2
Reputation: 140148
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})
Upvotes: 6
Reputation: 48057
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})
Upvotes: 6