Yebach
Yebach

Reputation: 1691

python group by not working

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

Answers (1)

Duncan
Duncan

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

Related Questions