Как получить значения объекта 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
1 ответ
Это не сработает:
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
даст вам неправильное имя класса, и это не будет правильно мариновать. Но исправить это почти так же просто. На самом деле, это приведено в качестве примера в документации:
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),)