Pythonic способ перебора экземпляров collection.Counter() в порядке убывания?

В Python 2 (точнее, 2.7) я хочу перебирать экземпляр collection.Counter в порядке убывания счета.

>>> import collections
>>> c = collections.Counter()
>>> c['a'] = 1
>>> c['b'] = 999
>>> c
Counter({'b': 999, 'a': 1})
>>> for x in c:
        print x
a
b

В приведенном выше примере кажется, что элементы повторяются в том порядке, в котором они были добавлены в экземпляр Counter.

Я хотел бы перебирать список с самого высокого на самый низкий. Я вижу, что строковое представление Counter делает это, просто интересно, есть ли рекомендуемый способ сделать это.

Ответы

Ответ 1

Вы можете выполнить итерацию по c.most_common(), чтобы получить элементы в нужном порядке. См. Также документацию Counter.most_common().

Пример:

>>> c = collections.Counter(a=1, b=999)
>>> c.most_common()
[('b', 999), ('a', 1)]

Ответ 2

Вот пример, чтобы перебирать коллекции Counter в Python:

>>>def counterIterator(): 
 import collections
 counter = collections.Counter()
 counter.update(('u1','u1'))
 counter.update(('u2','u2'))
 counter.update(('u2','u1'))
 for ele in counter:
  print(ele,counter[ele])
>>>counterIterator()
u1 3
u2 3

Ответ 3

Ваша проблема была решена только для возврата по убыванию, но вот как это сделать в целом. В случае, если кто-то из Google приходит сюда, вот как мне пришлось его решить. В основном то, что у вас выше, возвращает ключи для словаря внутри коллекций. Counter(). Чтобы получить значения, вам просто нужно передать ключ обратно в словарь следующим образом:

for x in c:
    key = x
    value = c[key]

У меня была более конкретная проблема, когда у меня было количество слов и я хотел отфильтровать низкочастотные. Трюк здесь заключается в том, чтобы сделать копию коллекций .Counter() или вы получите "RuntimeError: словарь измененный размер во время итерации", когда вы пытаетесь удалить их из словаря.

for word in words.copy():
    # remove small instance words
    if words[word] <= 3:
        del words[word]