Reputation: 359
I have a list with quite a few entries that looks like this:
first_list = [
{'manager': 'manager1', 'template_id': '12345', 'template_title': 'Template Title1'},
{'manager': 'manager2', 'template_id': '12346', 'template_title': 'Template Title2'},
{'manager': 'manager23', 'template_id': '12345', 'template_title': 'Template Title1'}]
I want to count how many times a template_id is in the list, then add those to a new list of dictionaries (or if there is a better way to do this, I'm all ears).
So end result would be:
second_list = [
{'template_id': '12345', , 'template_title': 'Template Title1', 'count': '5'},
{'template_id': '12346', , 'template_title': 'Template Title2', 'count': '3'},
{'template_id': '12347', , 'template_title': 'Template Title3', 'count': '4''}]
I'm not sure how to iterate through this properly to get the count of the template_id. Any help is greatly appreciate. Thank you!
Upvotes: 2
Views: 166
Reputation: 14216
So we can use itertools.groupby
to achieve the desired result. The caveat for itertools.groupby
is that your data must be pre-sorted on the grouped keys.
TO_KEEP = ['template_id', 'template_title']
def sort_key(item):
return [item.get(k) for k in TO_KEEP]
results = []
sorted_data = sorted(first_list, key=sort_key)
for k, v in itertools.groupby(sorted_data, key=sort_key):
temp = dict(zip(TO_KEEP, k))
temp.update({'count': len(list(v))})
results.append(temp)
print(results)
[{'template_id': '12345', 'template_title': 'Template Title1', 'count': 2},
{'template_id': '12346', 'template_title': 'Template Title2', 'count': 1}]
Upvotes: 1
Reputation: 17322
you could use Counter
from collections module with list comprehension:
from collections import Counter
count = Counter([e['template_id'] for e in first_list])
id_title = {e['template_id']: e['template_title'] for e in first_list}
second_list = [{'template_id': i, 'template_title': id_title[i], 'count': c} for i, c in count.items()]
output:
[{'template_id': '12345', 'template_title': 'Template Title1', 'count': 2},
{'template_id': '12346', 'template_title': 'Template Title2', 'count': 1}]
Upvotes: 0
Reputation: 887
A possible solution, without utilizing external libraries:
counts = {}
for d in first_list:
key = (d['template_id'], d['template_title'])
counts[key] = counts.get(key, 0) + 1
second_list = [{'template_id': k[0], 'template_title': k[1], 'counts': v} for k, v in counts.items()]
Upvotes: 1
Reputation: 3648
You can do this ny first creating a dictionary of dictionaries:
dict_1 = {}
for sub_dict in first_list:
template_id = sub_dict['template_id']
template_title = sub_dict['template_title']
if template_id not in dict_1:
dict_1[template_id] = {'template_id' : template_id, 'template_title': template_title, 'count' : 0}
dict_1[template_id]['count'] += 1
Now all you need to do is convert this to a list:
second_list = list(dict_1.values())
Upvotes: 0
Reputation: 22952
You can sort the list by template_id and the group items by template_id using itertools.groupby, like this:
import itertools
import operator
first_list = [
{"manager": "manager1", "template_id": "12345", "template_title": "Template Title1"},
{"manager": "manager2", "template_id": "12346", "template_title": "Template Title2"},
{"manager": "manager23", "template_id": "12345", "template_title": "Template Title1"},
]
get_template_id = operator.itemgetter("template_id")
first_list.sort(key=get_template_id)
second_list = []
for template_id, group in itertools.groupby(first_list, key=get_template_id):
group = list(group)
first = group[0]
entry = {
"template_id": template_id,
"template_title": first["template_title"],
"count": len(group),
}
second_list.append(entry)
print(second_list)
You get:
[
{'template_id': '12345', 'template_title': 'Template Title1', 'count': 2},
{'template_id': '12346', 'template_title': 'Template Title2', 'count': 1},
]
Upvotes: 1