Python для понимания вложенного словаря

У меня возникли проблемы с пониманием понимания вложенных словарей в Python 3. Результат, который я получаю из приведенного ниже примера, выводит правильную структуру без ошибок, но включает только одну из пар внутренний ключ: значение. Я не нашел примера понимания вложенного словаря, подобного этому; Поиск в Google «вложенного понимания словаря python» показывает устаревшие примеры, невложенные понимания или ответы, решенные с использованием другого подхода. Я могу использовать неправильный синтаксис.

Пример:

data = {outer_k: {inner_k: myfunc(inner_v)} for outer_k, outer_v in outer_dict.items() for inner_k, inner_v in outer_v.items()}

Этот пример должен вернуть исходный словарь, но с измененным внутренним значением myfunc.

Структура словаря external_dict, а также результат:

{outer_k: {inner_k: inner_v, ...}, ...}

person Turtles Are Cute    schedule 29.07.2013    source источник


Ответы (3)


{inner_k: myfunc(inner_v)} не является словарным пониманием. Это просто словарь.

Вместо этого вы, вероятно, ищете что-то вроде этого:

data = {outer_k: {inner_k: myfunc(inner_v) for inner_k, inner_v in outer_v.items()} for outer_k, outer_v in outer_dict.items()}

Ради удобочитаемости не встраивайте слишком много словарных и списочных понятий.

person Blender    schedule 29.07.2013
comment
Большое вам спасибо - если это кому-нибудь поможет, вот момент, который меня смутил: решение Blender имеет два изменения по сравнению с моим бывшим: перемещенная скобка и размещение внутренней "для" перед внешней. Первоначально у меня было правильно установлено предложение for, но с скобкой в ​​неправильном месте получалось NameError: глобальное имя «outer_v не определено». Затем та же ошибка с «for» в неправильном месте со скобкой в ​​​​правильном месте. - person Turtles Are Cute; 29.07.2013

Добавление разрывов строк и отступов:

data = {
    outer_k: {inner_k: myfunc(inner_v)} 
    for outer_k, outer_v in outer_dict.items()
    for inner_k, inner_v in outer_v.items()
}

... делает очевидным, что у вас на самом деле есть одно "двухмерное" понимание dict. То, что вы на самом деле хотите, вероятно:

data = {
    outer_k: {
        inner_k: myfunc(inner_v)
        for inner_k, inner_v in outer_v.items()
    } 
    for outer_k, outer_v in outer_dict.items()
}

(это именно то, что Блендер предложил в своем ответе, с добавлением пробелов).

person Zero Piraeus    schedule 29.07.2013
comment
Также очень полезно. Я рассмотрю сравнение этого с использованием dict comp для 1 оси в цикле for, а также лучший способ эстетически разбить его по строкам. - person Turtles Are Cute; 29.07.2013
comment
Что, если значение ключа external_k на самом деле является inner_k? - person Michael; 17.10.2018
comment
@ZeroPiraeus можно ли отфильтровать определенное измерение. Скажем, у меня есть dict[dim1,dim2], где 'dim1=['a','b',c]' и dim2=[1,2], и я хотел бы получить новый словарь, содержащий все значения dim1 и только dim2=1. Каждое значение dict[dim1,dim2] представляет собой массив. Я понял [ v for k,v in dict.items() if 'a' in k], но это возвращает 2-й список, и я хотел бы иметь 1-й список. - person Alexander Cska; 21.03.2019

{ok: {ik: myfunc(iv) for ik, iv in ov.items()} for ok, ov in od.items()}  

где
ok-внешний ключ
ik-внутренний ключ
ov-внешнее значение
iv-внутреннее значение od-внешний словарь Вот как я помню.

person Gajendra D Ambi    schedule 26.12.2018