Reputation: 309
I have this list of dictionaries:
[{'Total Incidents': '1', 'CrimeTime': '19'},
{'Total Incidents': '1', 'CrimeTime': '19'},
{'Total Incidents': '1', 'CrimeTime': '19'},
{'Total Incidents': '1', 'CrimeTime': '20'},
{'Total Incidents': '1', 'CrimeTime': '20'},
{'Total Incidents': '1', 'CrimeTime': '21'},
{'Total Incidents': '1', 'CrimeTime': '21'}]
I need to convert the value of 'Total Incidents' to int, and sum them up, for each incident that occured in the same hour (the minutes and seconds are irrelevant). The output should be something like this:
[{'Total Incidents': 3, 'CrimeTime': '19'},
{'Total Incidents': 2, 'CrimeTime': '20'},
{'Total Incidents': 2, 'CrimeTime': '21'}]
I have used this method:
[{ 'CrimeTime': g[0],
'Total Incidents': sum(map(lambda x: int(x['Total Incidents']), g[1])) }
for g in itertools.groupby(mydata, lambda x: x['CrimeTime']) ]
But unfortunately, sometimes it repeats 'CrimeTime' so I get two dictionaries with the same 'CrimeTime', instead of only one with the summed incidents. The original list is a lot bigger, I just used a short version to explain myself better.
Feel free to ask if you don't understand my question so that I can explain myself a bit better.
Upvotes: 1
Views: 965
Reputation: 73460
In most contexts (as in yours), itertools.groupby
works best if the data is sorted by the grouping key because it only groups adjacent elements:
key = lambda x: x['CrimeTime']
[
{'CrimeTime': k, 'Total Incidents': sum(int(x['Total Incidents']) for x in g)}
for k, g in itertools.groupby(sorted(mydata, key=key), key=key)
]
Using the generator expression instead of the map
-lambda
is mostly a matter of taste, but, at least in Python 2, saves you some resources by not building an intermediate list
.
Upvotes: 3
Reputation: 1025
This should work : (too late ;) )
[
{'CrimeTime': g[0], 'Total Incidents': sum(map(lambda x: int(x['Total Incidents']), g[1]))}
for g in
itertools.groupby(
sorted(data,key=lambda x:x.values()[0]), lambda x: x['CrimeTime'])
]
Upvotes: 1