Список групп по годам и подгруппы по месяцам в python

Допустим, у меня есть такой список:

list = [["A",datetime.datetime(1985,8,31,0,0)], ["B",datetime.datetime(2014,4,3,0,0)], ["C",datetime.datetime(2014,4,4,0,0)],["D",datetime.datetime(2014,6,9,0,0)], ["E",datetime.datetime(2015,6,1,0,0)], ["F",datetime.datetime(2015,2,7,0,0)]]

Как мне наиболее элегантно сгруппировать это по году и подгруппе по месяцам, чтобы получить вывод этого списка в Python, например:

newlist = [["A",datetime.datetime(1985,8,31,0,0)], [[["B",datetime.datetime(2014,4,3,0,0)], ["C",datetime.datetime(2014,4,4,0,0)]],["D",datetime.datetime(2014,6,9,0,0)]], [["E",datetime.datetime(2015,6,1,0,0)], ["F",datetime.datetime(2015,2,7,0,0)]]]

Таким образом, значения сгруппированы по годам, а затем по месяцам, и порядок сохраняется. Я импортирую модуль datetime в свой код

import datetime

и применяя strptime

kdate=year/month/day
date = datetime.datetime.strptime(kdate , "%m/%d/%Y")

Затем я сохраняю дату в списке. Список выглядит так, как указано выше

Любая причина, по которой подсписки синглтонов не вложены?

schwobaseggl 10.09.2018 10:31

@schwobaseggl: они «сгруппированы» по году и месяцу

Skandix 10.09.2018 12:20
0
2
484
1

Ответы 1

Используя itertools.groupby, вы можете группировать по годам, а затем по месяцам.

Выражение немного сложное и требует сортировки исходного списка перед применением любого выражения groupby, но оно позволяет получить достойный результат.

newlist = [[list(subgroup) for _, subgroup in groupby(group, key=lambda i: i[1].strftime("%m"))] for _, group in groupby(sorted(mylist, key=lambda i: i[1].strftime("%Y%m%d")), key=lambda i: i[1].strftime("%Y"))]

Исходный список отсортирован по году, месяцу и дню с использованием шаблона CCYYMMDD. Отсортированный список затем группируется по годам. Результирующий список в конечном итоге сгруппирован по месяцам.

Это вернет трехуровневый список, состоящий из:

  • Подсписки, перечисляющие каждый отдельный год, присутствующий в вашем первоначальном списке.
  • Подсписки по годам состоят из подсписок, в которых перечисляются каждый отдельный месяц относительно года.
  • Подсписки месяцев в конечном итоге состоят из групп, относящихся как к месяцу, так и к году. Эти нижние подсписки отсортированы по возрастанию дня.

Вот результат, полученный из вашего списка:

[[[['A', datetime.datetime(1985, 8, 31, 0, 0)]]], [[['B', datetime.datetime(2014, 4, 3, 0, 0)], ['C', datetime.datetime(2014, 4, 4, 0, 0)]], [['D', datetime.datetime(2014, 6, 9, 0, 0)]]], [[['F', datetime.datetime(2015, 2, 7, 0, 0)]], [['E', datetime.datetime(2015, 6, 1, 0, 0)]]]]

Это не совсем то, чего вы ожидаете. Но интерес этой структуры состоит в том, что она уважает иерархию дней, вложенных в месяцы, и месяцев, вложенных в годы. Его можно легко использовать в качестве входных данных для структуры цикла (например).

for year in newlist:
    for month in year:
        for day in month:
            # some code here.

Надеюсь, это поможет.

Это было большим подспорьем. Спасибо.

Shahnawaz Khan 11.09.2018 08:27

Другие вопросы по теме