копирование многоуровневых словарей Python - PullRequest
0 голосов
/ 10 февраля 2019

У меня ниже словарь Python как source

d1 = {
  'a': 1,
  'b': 2,
  'c': [{'d': 3, 'e': 4, 'un': 'wanted1', 'dont': 'needthis1'},
        {'d': 5, 'e': 6, 'un': 'wanted2', 'dont': 'needthis2'}]
  'xyz': 'abc',
  'zxy': 'cab',
  'wva': 'xyw'
}

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

d2 = {
  'some_attr_1': 1,  
  'some_attr_x': 2,
  'attr_some_z': [{'attr_x': 3, 'attrib': 4},
                  {'attr_x': 5, 'attrib': 6}]
}

Примечание:

  • Меня не интересуют все атрибуты source, например: мне не нужны ключи xyz, zxy и т. Д.
  • В основном, Хотите, чтобы значения некоторых ключей в source были сопоставлены с различными ключами в словаре target.

Мой текущий подход, как показано ниже, заключается в отображении между source и target ключами словаря.

attr_map1 = {
   'some_attr_1': 'a',
   'some_attr_x': 'b'
}

attr_map2 = {
  'attr_x': 'd',
  'attrib': 'e',
}

d2 = dict()
for k, v in attr_map1.items():
   d2[k] = d1[v]

l1 = list()
for d_elem in d1['c']:
   temp_dict = dict()
   for k, v in attr_map2.items():
       temp_dict[k] = d_elem[v]
   l1.append(temp_dict)
d2['attr_some_z'] = l1

Есть ли альтернативный, лучший и быстрый подход для достижения этой цели??

Я ищу решение в Python 2.7.

спасибо,

1 Ответ

0 голосов
/ 10 февраля 2019

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

d1 = {'a': 1, 'b': 2, 'c': [{'d': 3, 'e': 4}, {'d': 5, 'e': 6}]}
def build(d):
  return {f't_{a}':b if not isinstance(b, (dict, list)) else 
           list(map(build, b)) if isinstance(b, list) else build(b) for a, b in d.items()}

print(build(d1))

Вывод:

{
't_a': 1, 
 't_b': 2, 
 't_c': [
    {'t_d': 3, 't_e': 4}, 
    {'t_d': 5, 't_e': 6}
   ]
}

Редактировать: чтобы запустить это решение в Python2, замените f-string простой конкатенацией:

d1 = {'a': 1, 'b': 2, 'c': [{'d': 3, 'e': 4}, {'d': 5, 'e': 6}]}
def build(d):
   return {'t_'+a:b if not isinstance(b, (dict, list)) else 
       list(map(build, b)) if isinstance(b, list) else build(b) for a, b in d.items()}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...