首页 > 解决方案 > 如何按接收顺序获取 Counter 对象的值?

问题描述

任务:第一行包含整数 N。接下来的 N 行每行包含一个单词。输出应该是: 1) 在第一行,输出输入中不同单词的数量。2) 在第二行,根据输入中的出现输出每个不同单词的出现次数。我对#1没有任何困难。对于第 2 点,我使用 Counter 来获取单词的出现次数。但是,我很难按照收到的顺序打印它们。下面是我的代码。

from collections import Counter
from collections import OrderedDict
all_words=[]
for _ in range(int(raw_input())):
    name=raw_input()
    all_words.append(name)
uniqlst=list(set(all_words)) 
print len(uniqlst)##On the first line, output the number of distinct words from the input. 


x=OrderedDict(Counter(all_words)) #This is where I am having trouble to get values of x in the order it was received.
print " ".join(map(str,x.values()))

输入:

4
bcdef
abcdef
bcde
bcdef

我的代码的输出:

3
1 1 2

预期输出:

3
2 1 1

标签: pythonordereddictionary

解决方案


这是行不通的:

x=OrderedDict(Counter(all_words))

首先,您Counter通过迭代创建 a all_words。由于 aCounter只是底层的 a dict,根据您的 Python 版本,这可能是插入顺序、一致但任意顺序或显式随机顺序。

OrderedDict然后你通过迭代它来创建一个Counter。这将保留- 如果是任意顺序Counter,这将不是很有用。Counter

您要做的是创建一个可以做所有事情Counter但也可以做所有事情的类OrderedDict。这是微不足道的:

class OrderedCounter(Counter, OrderedDict):
    'Counter that remembers the order elements are first encountered'

这不是完美,因为它repr会给你错误的类名,而且它不会正确腌制。但修复它几乎一样简单。事实上,它在文档中作为示例给出

class OrderedCounter(Counter, OrderedDict):
    'Counter that remembers the order elements are first encountered'

    def __repr__(self):
        return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))

    def __reduce__(self):
        return self.__class__, (OrderedDict(self),)

推荐阅读