Pythonic way to iterate over a collections.Counter() instance in descending order?

Question:

In Python 2.7, I want to iterate over a collections.Counter instance in descending count order.

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

In the example above, it appears that the elements are iterated in the order they were added to the Counter instance.

I’d like to iterate over the list from highest to lowest. I see that the string representation of Counter does this, just wondering if there’s a recommended way to do it.

Asked By: Inactivist

||

Answers:

You can iterate over c.most_common() to get the items in the desired order. See also the documentation of Counter.most_common().

Example:

>>> c = collections.Counter(a=1, b=999)
>>> c.most_common()
[('b', 999), ('a', 1)]
Answered By: Sven Marnach

Your problem was solved for just returning descending order but here is how to do it generically. In case someone else comes here from Google here is how I had to solve it. Basically what you have above returns the keys for the dictionary inside collections.Counter(). To get the values you just need to pass the key back to the dictionary like so:

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

I had a more specific problem where I had word counts and wanted to filter out the low frequency ones. The trick here is to make a copy of the collections.Counter() or you will get “RuntimeError: dictionary changed size during iteration” when you try to remove them from the dictionary.

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

Here is the example to iterate the Counter in Python collections:

>>>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
 
Answered By: Chandra