What is a Pythonic way to count dictionary values in list of dictionaries
Question: For a list like this:

    
    
    for i in range(100):
        things.append({'count':1})
    
    for i in range(100):
        things.append({'count':2})
    

To count the number of `1` in list:

    
    
    len([i['count'] for i in things if i['count'] == 1])
    

What is a better way?


Answer: [collections.Counter](http://docs.python.org/2/library/collections.html#collections.Counter)

    
    
    >>> from collections import Counter
    >>> c = Counter([thing['count'] for thing in things])
    >>> c[1]               # Number of elements with count==1
    100
    >>> c[2]               # Number of elements with count==2
    100
    >>> c.most_common()    # Most common elements
    [(1, 100), (2, 100)]
    >>> sum(c.values())    # Number of elements
    200
    >>> list(c)            # List of unique counts
    [1, 2]
    >>> dict(c)            # Converted to a dict 
    {1: 100, 2: 100}
    

* * *

Perhaps you could do something like this?

    
    
    class DictCounter(object):
        def __init__(self, list_of_ds):
            for k,v in list_of_ds[0].items():
                self.__dict__[k] = collections.Counter([d[k] for d in list_of_ds])
    
    >>> new_things = [{'test': 1, 'count': 1} for i in range(10)]
    >>> for i in new_things[0:5]: i['count']=2
    
    >>> d = DictCounter(new_things)
    >>> d.count
    Counter({1: 5, 2: 5})
    >>> d.test
    Counter({1: 10})
    

Extended DictCounter to handle missing keys:

    
    
    >>> class DictCounter(object):
        def __init__(self, list_of_ds):
            keys = set(itertools.chain(*(i.keys() for i in list_of_ds)))
            for k in keys:
                self.__dict__[k] = collections.Counter([d.get(k) for d in list_of_ds])
    
    >>> a = [{'test': 5, 'count': 4}, {'test': 3, 'other': 5}, {'test':3}, {'test':5}]
    >>> d = DictCounter(a)
    >>> d.test
    Counter({3: 2, 5: 2})
    >>> d.count
    Counter({None: 3, 4: 1})
    >>> d.other
    Counter({None: 3, 5: 1})
    

