Search code examples
pythonpython-3.xdictionarycounterordereddictionary

How to get count dict of items but maintain the order in which they appear?


For example, I need to count how many times a word appears in a list, not sorted by frequency but with the order in which the words appear, i.e. insertion order.

from collections import Counter

words = ['oranges', 'apples', 'apples', 'bananas', 'kiwis', 'kiwis', 'apples']

c = Counter(words)

print(c)

So instead of: {'apples': 3, 'kiwis': 2, 'bananas': 1, 'oranges': 1}

I'd rather get: {'oranges': 1, 'apples': 3, 'bananas': 1, 'kiwis': 2}

And I don't really need this Counter method, any way that will produce correct result is OK for me.


Solution

  • You can use the recipe that uses collections.Counter and collections.OrderedDict:

    from collections import Counter, OrderedDict
    
    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),)
    
    words = ["oranges", "apples", "apples", "bananas", "kiwis", "kiwis", "apples"]
    c = OrderedCounter(words)
    print(c)
    # OrderedCounter(OrderedDict([('oranges', 1), ('apples', 3), ('bananas', 1), ('kiwis', 2)]))