How can I count occurrences of values in a list of dicts?

Question:

I have this list of dicts:

[{'Description': 'LARCENY'}, {'Description': 'LARCENY'}, {'Description': 'BURGLARY'}, {'Description': 'ROBBERY - STREET'}, {'Description': 'COMMON ASSAULT'}, {'Description': 'COMMON ASSAULT'}, {'Description': 'AUTO THEFT'}, {'Description': 'AUTO THEFT'}, {'Description': 'ROBBERY - STREET'}, {'Description': 'COMMON ASSAULT'}, {'Description': 'COMMON ASSAULT'}, {'Description': 'BURGLARY'}, {'Description': 'BURGLARY'}, {'Description': 'LARCENY'}, {'Description': 'ROBBERY - COMMERCIAL'}, {'Description': 'COMMON ASSAULT'}, {'Description': 'COMMON ASSAULT'}, {'Description': 'COMMON ASSAULT'}]

I need to make a function that iterates over those dictionaries and counts how many times each type of crime has occurred. The output should be a list of dicts like this:

[{'LARCENY' : 3}, {'BURGLARY' : 2}, {'ROBBERY - STREET' : 3}...

For each type of crime, I need to know how many times that crime as occurred.
This is what I have so far:

result = {}
for k in data:
   if 'Description' in k:
    result[k['Description']] = result.get(k['Description'], 0) + 1 

But the output given gives me everything in the same dict, but I want them to be in a list of dicts, each crime with each dict.

Feel free to ask any question if you don’t understand mine.

Asked By: Stagg

||

Answers:

Given the result you’ve got so far…

>>> result = {'LARCENY' : 3, 'BURGLARY' : 2, 'ROBBERY - STREET' : 3}
>>> result = [{k:v} for k,v in result.items()]
>>> result
[{'BURGLARY': 2}, {'LARCENY': 3}, {'ROBBERY - STREET': 3}]
Answered By: Kevin

While your data structure doesn’t make sense as noted above, you can solve this easily using the Counter class from collections.

from collections import Counter

crimes = [{'Description': 'LARCENY'}, {'Description': 'LARCENY'}, {'Description': 'BURGLARY'}, {'Description': 'ROBBERY - STREET'}, {'Description': 'COMMON ASSAULT'}, {'Description': 'COMMON ASSAULT'}, {'Description': 'AUTO THEFT'}, {'Description': 'AUTO THEFT'}, {'Description': 'ROBBERY - STREET'}, {'Description': 'COMMON ASSAULT'}, {'Description': 'COMMON ASSAULT'}, {'Description': 'BURGLARY'}, {'Description': 'BURGLARY'}, {'Description': 'LARCENY'}, {'Description': 'ROBBERY - COMMERCIAL'}, {'Description': 'COMMON ASSAULT'}, {'Description': 'COMMON ASSAULT'}, {'Description': 'COMMON ASSAULT'}]

c = Counter()
for item in crimes:
    c[item["Description"]] += 1

print(c)

This gives the output of:

Counter({'COMMON ASSAULT': 7, 'BURGLARY': 3, 'LARCENY': 3, 'AUTO THEFT': 2, 'ROBBERY - STREET': 2, 'ROBBERY - COMMERCIAL': 1})

I’d recommend looking at the Counter class whenever you want to count things.

Answered By: Michael Lampe

Looks like you want to maintain the order of occurrence of the crimes as well.

So, use collections.OrderedDict instead of normal dict.

>>> from collections import OrderedDict
>>> counter = OrderedDict()
>>> for item in data:
...     if 'Description' in item:
...         counter[item['Description']] = counter.get(item['Description'], 0) + 1

Now, just construct a new dictionary with each and every key, value pair out of the counter, like this

>>> from pprint import pprint
>>> pprint([{k: v} for k, v in counter.items()])
[{'LARCENY': 3},
 {'BURGLARY': 3},
 {'ROBBERY - STREET': 2},
 {'COMMON ASSAULT': 7},
 {'AUTO THEFT': 2},
 {'ROBBERY - COMMERCIAL': 1}]

From the comments,

After I get the desired output I will need to separate the keys and the values into diferent lists,

Then, don’t create list of dictionaries. Directly create two lists, with keys and values, from the counter itself, like this

>>> list(counter.keys())
['LARCENY', 'BURGLARY', 'ROBBERY - STREET', 'COMMON ASSAULT', 'AUTO THEFT', 'ROBBERY - COMMERCIAL']
>>> list(counter.values())
[3, 3, 2, 7, 2, 1]
Answered By: thefourtheye
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.