сортировать вложенный defaultdict в списке словарей

Не могу понять, как упорядочить этот список, состоящий из вложенных defaultdicts. С этим я смог отсортировать по ключу «регистрации» и значению «классы»;

sorted(dict1.items(), key=itemgetter(1), reverse=True)

Что произведено;

[('registration', {'count': 11, 'classes': Counter({'class1': 5, 'class2': 5, 'class3': 1}), 'date': defaultdict(<function date_record at 0x7fc173646500>, {datetime.date(2016, 6, 7): {'count': 1, 'hour': Counter({16: 1})}, datetime.date(2016, 6, 6): {'count': 10, 'hour': Counter({16: 5, 14: 2, 8: 1, 10: 1, 12: 1})}})})]

Однако теперь я пытаюсь отсортировать по дате, которая является вложенным defaultdict. Я пытаюсь упорядочить по дате в хронологическом порядке (от - до), а затем, наконец, упорядочить "час" Counter() в хронологическом порядке (для справки; 8 = 8 утра и 16 = 16:00).

Таким образом, приведенный выше defaultdict должен выглядеть так:

[('registration', {'count': 11, 'classes': Counter({'class1': 5, 'class2': 5, 'class3': 1}), 'date': defaultdict(<function date_record at 0x7fc173646500>, {datetime.date(2016, 6, 6): {'count': 10, 'hour': Counter({16: 5, 14: 2, 12: 1, 10: 1, 8: 1})}, datetime.date(2016, 6, 7): {'count': 1, 'hour': Counter({16: 1, 14: 4})}})})]

Я просто не могу понять, как получить доступ к defaultdict. Любое руководство о том, как я могу получить к нему доступ в сортировке?


person user1165419    schedule 15.06.2016    source источник


Ответы (1)


Параметр key для сортировки или сортировки может быть любым вызываемым. Этот вызываемый объект должен возвращать объекты, которые напрямую сопоставимы с операторами Python == и <=. Нет необходимости, чтобы объект, переданный как key, был вызываемым, возвращаемым itemgetter или какой-либо другой сложной конструкцией.

Нет необходимости, чтобы это была короткая функция — одно выражение, которая также может быть в лямбда-выражении.

Итак, просто определите функцию, пусть она будет иметь необходимый размер, чтобы получить атрибуты, которые вы хотите сравнить. Если имеется более одного значения, верните последовательность с этими значениями. Передайте эту функцию для именованного параметра key в sort.

Я не уверен, смогу ли я понять, как вы можете упорядочить свои ключи/значения внутри вашего вложенного каталога date, но это может быть что-то вроде:

def sort_key(item):
    dates = list(item["date"].items())
    # the key in the lambda bellow will get 
    # tuples with the datetime and subdictionary for each date:

    dates.sort(key=lambda inner_date: (inner_date[0], sorted(inner_date[1]["hour"].keys())
    return dates

Обратите внимание, что вам нужна внутренняя сортировка в rder, чтобы ваши ключи также учитывали значения «часа» - я сделал это, заставив каждый ключ в сортировке каждой «даты» каждого из ваших элементов списка возвращать кортеж, где первый элемент - это сама "дата", используемая в качестве ключа, вторая - отсортированный список значений, отображаемых в счетчике (но не количество для каждого значения).

Если этот вторичный ключ слишком сложен для лямбда-выражения, просто создайте для него другую функцию. Эти функции будут вызываться только один раз для каждого элемента во внешнем списке, который вы сортируете, поэтому ваша производительность должна быть в порядке.

person jsbueno    schedule 15.06.2016
comment
Эй jsbueno, спасибо за ваш ответ. Я пробовал это выше, и я думаю, что есть проблема с захватом ключа «дата» dates = list(item["date"].iteritems()) TypeError: list indices must be integers, not str (я пробовал с .items то же самое). По какой-то причине он не распознает значение ключа и думает, что это индекс списка. Любая идея о том, как я могу получить ключ? - person user1165419; 16.06.2016
comment
Я немного поиграл с этим и сделал это dates = list(item[0][1]["date"].items()), но, как вы понимаете, это дает только первый результат. Я думаю, что мне нужна лямбда-функция для перебора [0][1], но я не смог понять это с примерами, которые я видел. - person user1165419; 16.06.2016
comment
Сортировка разобралась с этим, используя цикл for, а затем отсортировав его там. Спасибо за помощь/подсказку! - person user1165419; 16.06.2016