Reputation: 1691
I have a list of dictionaries and I want to group them by a field of type string
recs = [
{'r_date': datetime.date(2014, 1, 1), 'r_time_start': datetime.time(7, 0), 'r_item1_name': 'Sef', 'r_time_end': datetime.time(12, 0)},
{'r_date': datetime.date(2014, 1, 1), 'r_time_start': datetime.time(8, 0), 'r_item1_name': 'Moj\xc4\x8dca', 'r_time_end': datetime.time(15, 0)},
{'r_date': datetime.date(2014, 1, 1), 'r_time_start': datetime.time(9, 0), 'r_item1_name': 'Student1', 'r_time_end': datetime.time(19, 0)},
{'r_date': datetime.date(2014, 1, 1), 'r_time_start': datetime.time(12, 0), 'r_item1_name': 'Student2', 'r_time_end': datetime.time(19, 0)},
{'r_date': datetime.date(2014, 1, 2), 'r_time_start': datetime.time(7, 0), 'r_item1_name': 'Sef', 'r_time_end': datetime.time(12, 0)},
{'r_date': datetime.date(2014, 1, 2), 'r_time_start': datetime.time(8, 0), 'r_item1_name': 'Moj\xc4\x8dca', 'r_time_end': datetime.time(15, 0)},
{'r_date': datetime.date(2014, 1, 2), 'r_time_start': datetime.time(9, 0), 'r_item1_name': 'Student1', 'r_time_end': datetime.time(19, 0)},
{'r_date': datetime.date(2014, 1, 2), 'r_time_start': datetime.time(12, 0), 'r_item1_name': 'Student2', 'r_time_end': datetime.time(19, 0)},
{'r_date': datetime.date(2014, 1, 3), 'r_time_start': datetime.time(7, 0), 'r_item1_name': 'Sef', 'r_time_end': datetime.time(12, 0)},
{'r_date': datetime.date(2014, 1, 3), 'r_time_start': datetime.time(8, 0), 'r_item1_name': 'Moj\xc4\x8dca', 'r_time_end': datetime.time(15, 0)},
{'r_date': datetime.date(2014, 1, 3), 'r_time_start': datetime.time(9, 0), 'r_item1_name': 'Student1', 'r_time_end': datetime.time(19, 0)},
{'r_date': datetime.date(2014, 1, 3), 'r_time_start': datetime.time(12, 0), 'r_item1_name': 'Student2', 'r_time_end': datetime.time(19, 0)},
{'r_date': datetime.date(2014, 1, 4), 'r_time_start': datetime.time(7, 0), 'r_item1_name': 'Sef', 'r_time_end': datetime.time(12, 0)},
{'r_date': datetime.date(2014, 1, 4), 'r_time_start': datetime.time(8, 0), 'r_item1_name': 'Moj\xc4\x8dca', 'r_time_end': datetime.time(15, 0)},
{'r_date': datetime.date(2014, 1, 4), 'r_time_start': datetime.time(9, 0), 'r_item1_name': 'Student1', 'r_time_end': datetime.time(19, 0)},
{'r_date': datetime.date(2014, 1, 4), 'r_time_start': datetime.time(14, 0), 'r_item1_name': 'Namestnik', 'r_time_end': datetime.time(22, 0)},
{'r_date': datetime.date(2014, 1, 5), 'r_time_start': datetime.time(7, 0), 'r_item1_name': 'Sef', 'r_time_end': datetime.time(12, 0)},
{'r_date': datetime.date(2014, 1, 5), 'r_time_start': datetime.time(8, 0), 'r_item1_name': 'Moj\xc4\x8dca', 'r_time_end': datetime.time(15, 0)},
{'r_date': datetime.date(2014, 1, 5), 'r_time_start': datetime.time(9, 0), 'r_item1_name': 'Student1', 'r_time_end': datetime.time(19, 0)},
{'r_date': datetime.date(2014, 1, 5), 'r_time_start': datetime.time(14, 0), 'r_item1_name': 'Namestnik', 'r_time_end': datetime.time(22, 0)},
{'r_date': datetime.date(2014, 1, 6), 'r_time_start': datetime.time(7, 0), 'r_item1_name': 'Sef', 'r_time_end': datetime.time(12, 0)},
{'r_date': datetime.date(2014, 1, 6), 'r_time_start': datetime.time(8, 0), 'r_item1_name': 'Moj\xc4\x8dca', 'r_time_end': datetime.time(15, 0)},
{'r_date': datetime.date(2014, 1, 6), 'r_time_start': datetime.time(9, 0), 'r_item1_name': 'Student1', 'r_time_end': datetime.time(19, 0)},
{'r_date': datetime.date(2014, 1, 6), 'r_time_start': datetime.time(14, 0), 'r_item1_name': 'Namestnik', 'r_time_end': datetime.time(22, 0)}]
I want to get a list of dict grouped by r_item1_name
grouped = [{"r_item1_name": "Sef","AllData" : [{record_of_sef},{another_record_of_sef},{another_record_of_sef}] }]
for key, items in itertools.groupby(recs, operator.itemgetter('r_item1_name')):
grupirani1.append({"r_item1_name": key, "AllData": list(items)})
If I group by a filed of type date (r_date) the code groups as expected.
Any ideas why?
Upvotes: 1
Views: 1023
Reputation: 95712
itertools.groupby
requires the input data be already sorted on the key used for grouping. Only consecutive values with the same key get grouped so if the data isn't sorted you will get separate groups for each block with the same value.
I reformatted the data in your question so it is possible to see the individual items. It should now be clear that it is sorted by r_date
so grouping will work on that field but you'll need to sort it to group on any other field.
Upvotes: 6