2017-02-06 3 views
2

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

dict1 = {'a': 1, 
     'b': 2, 
     'c': 3, 
     'd': 4, 
     'x': 5} 

и

dict2 = {'a': 'start', 
     'b': 'start', 
     'c': 'end', 
     'd': 'end'} 

Я пытаюсь создать новый словарь, который отображает значения start и end как ключи к словарю, что бы содержат информацию о dict1, сохраняя при этом значения, отсутствующие в dict2, например:

dict3 = {'start': {'a': 1, 'b': 2}, 
     'end': {'c': 3, 'd': 4}, 
     'x': {'x': 5} 
     } 

ответ

2

Использование dict.setdefault() для создания вложенных словарей в dict3, если еще не существует, и dict.get() для определения ключа в выходном верхнего уровня словаря:

dict3 = {} 
for k, v in dict1.items(): 
    nested = dict3.setdefault(dict2.get(k, k), {}) 
    nested[k] = v 

Так dict2.get(k, k) будет производить значение из dict2 для заданного ключа от dict1, используя сам ключ по умолчанию. Итак, для ключа 'x', который будет производить 'x', так как для этого ключа нет отображения в dict2.

Демо:

>>> dict3 = {} 
>>> for k, v in dict1.items(): 
...  nested = dict3.setdefault(dict2.get(k, k), {}) 
...  nested[k] = v 
... 
>>> dict3 
{'start': {'a': 1, 'b': 2}, 'end': {'c': 3, 'd': 4}, 'x': {'x': 5}} 
+0

читаемость примечание: если вы это сделаете, * пожалуйста * оставить комментарий относительно того, что это делает. Это использует setdefault по-новому и как таковое будет довольно загадочным без какого-либо объяснения. – TemporalWolf

+0

@TemporalWolf это использует 'dict.setdefault()' *, как задумано *. Я не уверен, что такое роман о том, как он здесь используется. –

+0

Может быть очевидно, как это работает для вас, но мне было непонятно, и я бы подумал об этом месте, где [блок или встроенные комментарии] (https://google.github.io/styleguide/pyguide.html?showone = Комментарии # Комментарии): «Сложные операции получают несколько строк комментариев до начала операций. Неочевидные получаются комментарии в конце строки». – TemporalWolf

1

Я на самом деле понял это, абстрагируясь от примера и набрав свой вопрос здесь (возможно, должен был сделать это раньше ...). В любом случае: Yay!

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

dict3 = dict() 

for k, v in dict1.items(): 
    # if the key of dict1 exists also in dict2 
    if k in dict2.keys(): 
     # get its value (the keys-to-be for the new dict3) 
     new_key = dict2[k] 
     # if the new key is already in the new dict 
     if new_key in dict3.keys(): 
      # appends new dict entry to dict3 
      dict3[new_key].update({k: v}) 
     # otherwise create a new entry 
     else: 
      dict3[new_key] = {k: v} 
    # if there is no corresponding mapping present 
    else: 
     # treat the original key as the new key and add to dict3 
     no_map = k 
     dict3[no_map] = {k: v} 
Смежные вопросы