Преобразовать ключи вложенного словаря в верхний регистр - PullRequest
1 голос
/ 22 января 2020

Есть словарь:

data = {'Common': {'height': 165, 'weight': 70, 'measure': ['cm', 'kg']},
         'Man': 'handsome',
         'Woman': {'feature': 'pretty', 'weight': 50},
         'Dog': {'feature': 'barks', 'height': 10, 'weight': 20}}

Хотел бы преобразовать только ключи словаря в UPPERCASE.

Попробовал следующий код:

d = {}
d1 = {}
for k, v in data.items():
    if isinstance(v, dict):
        for i, j in v.items():
            d1[i.upper()] = j
        d[k.upper()] = d1
    else:
        d[k.upper()] = v

print(d)

... which производит вывод с ненужными ключами и рационализацией роста и веса следующим образом:

{'COMMON': {'HEIGHT': 10, 'WEIGHT': 20, 'MEASURE': ['cm', 'kg'], 'FEATURE': 'barks'}, 
    'MAN': 'handsome', 
  'WOMAN': {'HEIGHT': 10, 'WEIGHT': 20, 'MEASURE': ['cm', 'kg'], 'FEATURE': 'barks'}, 
    'DOG': {'HEIGHT': 10, 'WEIGHT': 20, 'MEASURE': ['cm', 'kg'], 'FEATURE': 'barks'}}

Мой ожидаемый вывод:

{'COMMON': {'HEIGHT': 165, 'WEIGHT': 70, 'MEASURE': ['cm', 'kg']},
 'MAN': 'handsome',
 'WOMAN': {'FEATURE': 'pretty', 'WEIGHT': 50},
 'DOG': {'FEATURE': 'barks', 'HEIGHT': 10, 'WEIGHT': 20}}
  1. Куда я иду не так?
  2. Как правильно понимать словарь, как {{i.upper(): j} if isinstance(j, dict) else {k.upper(): v} for k, v in data.items() for i, j in v.items()}?

Ответы [ 3 ]

2 голосов
/ 22 января 2020

Вы можете сделать что-то подобное, скопировать на другие dict необходимые ключи:

data = {'Common': {'height': 165, 'weight': 70, 'measure': ['cm', 'kg']},
        'Man': 'handsome',
        'Woman': {'feature': 'pretty', 'weight': 50},
        'Dog': {'feature': 'barks', 'height': 10, 'weight': 20}}
data2 = {}
for k in data.keys():
    data2[k.upper()] = data[k]

ОБНОВЛЕНИЕ: Если вы хотите изменить не только ключи на уровне 1, вы должны использовать рекурсивную функцию:

data = {'Common': {'height': 165, 'weight': 70, 'measure': ['cm', 'kg']},
        'Man': 'handsome',
        'Woman': {'feature': 'pretty', 'weight': 50},
        'Dog': {'feature': 'barks', 'height': 10, 'weight': 20}}

def keys_to_upper(dict1):
    dict2 = {}
    for k in dict1.keys():
        if isinstance(dict1[k], dict):
            dict2[k.upper()] = keys_to_upper(dict1[k])
        else:
            dict2[k.upper()] = dict1[k]
    return dict2

d2 = keys_to_upper(data)
1 голос
/ 22 января 2020

Понимание списка быстрее, потому что оно оптимизировано для Python interpreter, чтобы обнаружить предсказуемую модель во время looping. Помимо синтактических c преимуществ list comprehensions, они часто бывают быстрее или быстрее эквивалентного использования map.

data = {'Common': {'height': 165, 'weight': 70, 'measure': ['cm', 'kg']},
        'Man': 'handsome',
        'Woman': {'feature': 'pretty', 'weight': 50},
        'Dog': {'feature': 'barks', 'height': 10, 'weight': 20}}

    for k, v in data.items():
      if isinstance(v, dict):
        data[k.upper()] = data.pop(k)

выход>

data = {'COMMON': {'height': 165, 'weight': 70, 'measure': ['cm', 'kg']},
        'Man': 'handsome',
        'WOMAN': {'feature': 'pretty', 'weight': 50},
        'DOG': {'feature': 'barks', 'height': 10, 'weight': 20}}
1 голос
/ 22 января 2020

Проблема с вашим кодом заключается в том, что вы переназначаете d1, если значением является словарь. Вы можете решить эту проблему, используя copy.deepcopy():

Код:

from copy import deepcopy

d = {}
d1 = {}
for k, v in data.items():
    if isinstance(v, dict):
        for i, j in v.items():
            d1[i.upper()] = j
        d[k.upper()] = deepcopy(d1)
    else:
        d[k.upper()] = v

Выход:

>>> d
{'COMMON': {'HEIGHT': 165, 'WEIGHT': 70, 'MEASURE': ['cm', 'kg']},
 'MAN': 'handsome',
 'WOMAN': {'FEATURE': 'pretty', 'WEIGHT': 50},
 'DOG': {'FEATURE': 'barks', 'HEIGHT': 10, 'WEIGHT': 20}}

В качестве альтернативы словарному пониманию:

>>> {k.upper(): {i.upper(): j for i, j in v.items()} if isinstance(v, dict) else v for k, v in data.items()}
{'COMMON': {'HEIGHT': 165, 'WEIGHT': 70, 'MEASURE': ['cm', 'kg']},
 'MAN': 'handsome',
 'WOMAN': {'FEATURE': 'pretty', 'WEIGHT': 50},
 'DOG': {'FEATURE': 'barks', 'HEIGHT': 10, 'WEIGHT': 20}}
...