简体   繁体   中英

Python: Counting occurrences of List element within List

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?

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

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})

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})

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)}

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())))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM