Python:计算列表元素在列表中出现的次数

7
我正试图统计列表中元素的出现次数,如果这些元素也是列表。顺序也很重要。
[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 }

一个重要因素是['a', 'b', 'c'] != ['c', 'b', 'a']

我已经尝试了:

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

这两种方式都导致了 ['a', 'b', 'c'] = ['c', 'b', 'a'] 这个结果,这是我不想要的。

我还尝试过:

from collections import counter
print( Counter( lst ) )

这样做只会导致错误,因为在字典中无法使用lists作为keys

有没有其他方法来实现这个功能?


1
你目前尝试了什么? - dmitryro
2
tuple(['a', 'b', 'c']) == tuple(['c', 'b', 'a']) gives me False - Savir
由于“列表不能用作字典中的键”,您所期望的输出是不可能的;那么您想要什么呢? - Scott Hunter
5个回答

6

列表是不可哈希的,但您可以使用元组作为解决方法:

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}

输出:

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

或者,如果你真的想使用列表,你可以创建一个自定义类来模仿字典哈希列表的功能:

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']])

输出:

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

元组解决方案很好,可以得到几乎一行的解决方案! - Olivier

6

你不能将 list 作为 dict 的键,因为字典只允许不可变对象作为其键。因此,你需要先将对象转换为元组。然后,你可以使用 collections.Counter 来获取每个元组的计数:

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

6

只需在与可哈希的等效类型上使用collections.Counter:元组:

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)

结果:

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

2

使用列表的另一种实现方式

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

如果你想要一个字典,你只需要将最后一部分更改为。
output = {element:l1.count(element) for element in unique(l1)}

2

不要使用list作为变量名。

如果您不想使用任何模块,可以尝试以下方法:

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)

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

您也可以使用默认字典:
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())))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接