Python Counter: 打印计数为x的键

7 投票
6 回答
7955 浏览
提问于 2025-04-18 17:05

假设我有一个 Counter 对象,它代表了一组单词:

>>> words = ['hello', 'hello', 'hello', 'world']
>>> counter = Counter(words)

找出哪些单词的计数是1,有一种方法就是遍历 counter

for word, count in counter.items():
    if count == 1:
        print(word)

有没有更简单或更好的方法呢?也就是说,能不能“反转” counter,来找出计数为 x 的单词?

6 个回答

0

你可以用列表推导式来检查每个元素出现的次数。

>>> words = ['hello', 'hello', 'hi', 'hi', 'world', 'foo', 'bar']
>>> from collections import Counter
>>> counter = Counter(words)
>>> [i for i in counter if counter[i] == 1]
['world', 'bar', 'foo']

你也可以在原始列表上使用 count() 函数。

>>> [i for i in words if words.count(i) == 1]
['world', 'foo', 'bar']
0

你可以使用 defaultdict 这个工具:

import collections
d = collections.defaultdict(list)
for word, count in counter.items():
    d[count].append(word)

然后你可以这样做:

d[1]

这样就能得到所有出现一次的单词(因为可能会有一个或多个单词)。

3

你的 Counter 对象把每个单词当作“钥匙”,然后把这个单词出现的次数当作“值”来存储。

如果你想实现你想要的功能,你需要把出现的次数当作“钥匙”,而把单词的列表当作“值”来使用:

wordDict = {}
for word, count in counter.items():
    if count in wordDict:
        wordDict[count].append(word)
    else:
        wordDict[count] = [word]

这样你就可以用 wordDict[2] 来获取出现了两次的单词列表。

5

我觉得把每个值为1的元素放到一个列表里会更好。这里有一种很Python风格的方法来做到这一点:

new_list = [w for w in words if counter[w] == 1]

这样,你就能把计数器中每个值为1的单词都存储在words里。

举个例子,如果你的列表里还有另一个字符串,比如test

words = ['hello', 'hello', 'hello', 'world', 'test']

那么,新的列表里就会有worldtest这两个值。

6

要反转任何映射,比如一个 Counter、一个 dict 或者其他任何东西,你可以这样做:

rev = {v: k for k, v in d.items()}

然后你可以像使用其他字典一样使用它:

key_whose_count_is_10 = rev[10]

如果有两个键的值是一样的,那么这个值会随机映射到其中一个键上。这其实是你问题的一部分。你在问“哪个”键的计数是 x;如果有三个键的计数都是 x,你想怎么处理呢?


如果你只打算查询一次,而不是多次查询,直接遍历会更高效。至于哪种方式更清晰(这几乎总是更重要),这可以讨论。这里有一种方法可以做对比:

key_whose_count_is_10 = next(k for k, v in d.items() if v==10)

撰写回答