如何按收到顺序获得Counter对象的值?

时间:2018-09-04 20:21:12

标签: python ordereddictionary

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

href

输入:

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

1 个答案:

答案 0 :(得分:0)

这行不通:

x=OrderedDict(Counter(all_words))

首先,您要通过迭代Counter来创建all_words。由于Counter只是底层的dict,具体取决于您的Python版本,所以可能是插入顺序,一致但任意的顺序或显式随机的顺序。

然后,通过迭代OrderedDict创建一个Counter。这样可以保留Counter的顺序,如果Counter处于任意顺序,则不会很有用。

您要做的是创建一个类,该类既可以执行Counter的所有工作,又可以完成OrderedDict的所有工作。这很简单:

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

这不是完美的 ,因为它的repr会给您错误的类名,而且泡菜也不会正确。但是解决这个问题几乎很简单。实际上,它是given as an example in the docs

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