Stagg
Stagg

Reputation: 309

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

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.

Upvotes: 3

Views: 10255

Answers (3)

Michael Lampe
Michael Lampe

Reputation: 674

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.

Upvotes: 6

thefourtheye
thefourtheye

Reputation: 239683

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]

Upvotes: 4

Kevin
Kevin

Reputation: 76254

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

Upvotes: 2

Related Questions