比较Python中的计数器列表

时间:2018-12-09 17:14:37

标签: python counter

我在python中有一个计数器列表:

[Counter({12.011: 30.0, 15.999: 2.0}),
Counter({12.011: 12.0, 15.999: 2.0}),... Counter({12.011: 40.0, 
15.999: 5.0, 79.904: 5.0})]

如何找到每个Counter元素的计数。计数器给我一个无法散列的错误。我认为的另一种方法是在嵌套的for循环中遍历列表,检查每个计数器是否等于列表中的任何其他计数器,并相应地增加字典。有更好的解决方案吗?

2 个答案:

答案 0 :(得分:3)

您可以将每个Counter转换为键,值(项目)元组的冻结集,然后将其用作传递给Counter的元素(因为Frozenset是可哈希的),例如:

import random

from collections import Counter

random.seed(42)

counts = [Counter([random.randint(0, 2) for _ in range(10)]) for _ in range(10)]

uniques = {frozenset(e.items()): e for e in counts}

counters_count = Counter(map(lambda e : frozenset(e.items()), counts))

for key, count in counters_count.items():
    print uniques[key], count

输出

Counter({0: 7, 1: 2, 2: 1}) 1
Counter({1: 4, 2: 4, 0: 2}) 1
Counter({0: 4, 1: 4, 2: 2}) 2
Counter({0: 4, 1: 3, 2: 3}) 1
Counter({0: 5, 2: 3, 1: 2}) 1
Counter({1: 5, 2: 5}) 1
Counter({0: 5, 1: 4, 2: 1}) 1
Counter({0: 4, 2: 4, 1: 2}) 1
Counter({2: 4, 0: 3, 1: 3}) 1

答案 1 :(得分:3)

在Python <= 3.6中,您最好的选择可能是将每个Counter与每个其他Counter进行比较。

在Python> = 3.7中,有更好的方法。由于Counterdict的子类,并且dict现在保持其顺序,因此可以将每个Counter对象的字符串表示形式用作其哈希值。

这有点棘手,但可以:

from collections import Counter

li = [Counter({'a': 1, 'b': 2, 'c': 3}),
      Counter({'a': 1, 'b': 2, 'c': 4}),
      Counter({'a': 1, 'b': 3, 'c': 3}),
      Counter({'a': 1, 'b': 2, 'c': 3})]


Counter.__hash__ = lambda counter: hash(str(counter))

print(Counter(li))
# Counter({Counter({'c': 3, 'b': 2, 'a': 1}): 2,
#          Counter({'c': 4, 'b': 2, 'a': 1}): 1,
#          Counter({'b': 3, 'c': 3, 'a': 1}): 1})