Выравнивание словаря словарей повышает ошибку атрибута

#python #list #dictionary #flatten

Вопрос:

У меня есть словарь:

 dict1 = {
    'conf1' : {'subconf11' : True, 'subconf12' : False}, 
    'conf2' : False, 
    'conf3' : {'subconf31' : True, 'subconf32' : False, 'subconf33' : False}, 
    'conf4' : 'On'
}
 

Я хочу свести его к списку кортежей, чтобы:

 list1 = [
    ('conf1',('subconf11',True)),
    ('conf1',('subconf12',False)),
    ('conf2',False),
    ('conf3',('subconf31',True)),
    ('conf3',('subconf32',False)),
    ('conf3',('subconf33',False)),
    ('conf4','On')
]
 

Я попробовал что-то вроде:

 primary_conf_list = list(dict1.keys())
list2 = [(i,list[dict1[i].items()]) for i in primary_conf_list]
 

Но по понятным причинам это приводит меня к ошибке для тех, где значение не является словарем, а либо bool, либо строковым значением. Например dict1['conf2'] , dict1['conf4'] И.

Вот точное сообщение об ошибке:

 AttributeError: 'bool' object has no attribute 'items'
 

Пожалуйста, помогите мне достичь этого.

Комментарии:

1. Вам нужны вложенные циклы для создания кортежа для каждого элемента во вложенных словарях.

Ответ №1:

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

 list2 = []
for key, val in dict1.items():
    if isinstance(val, dict):
        for subkey, subval in val.items():
            list2.append((key, (subkey, subval)))
    else:
        list2.append(key, val)
 

Комментарии:

1. @Barmer спасибо, это то, чего я хотел. Один вопрос, насколько мне известно, чем isinstance(val, dict) отличается от type(val) is dict поведения. Я видел случаи (особенно сценарии cpython), когда type() совпадение не срабатывало. Но isinstance() работает почти для всех практических целей.

2. isinstance() будет работать для подклассов, таких как defaultdict .

3. @Barmer Не могли бы вы, пожалуйста, преобразовать свой ответ в рекурсивный код для словаря словарей. Например subconf31 , может быть сам словарь словарей. пример: 'subconf31' : { 'subconf311' : { 'subconf3111' : True, 'subconf31112' : False}, 'subconf312' : True}