简体   繁体   中英

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.

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]

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM