Как объединить два словаря (defaultdict), которые имеют общие ключи, но разные «уникальный идентификатор: значения списка»?

В данном словаре defaultdict(dict) тип данных:

Скажи, что это dict1

{726: {'X': [3.5, 3.5, 2.0], 'Y': [2.0, 0.0, 0.0], 'chr': [2, 2, 2]}, 128: {'X': [0.5, 4.0, 4.0], 'Y': [4.0, 3.5, 3.5], 'chr': [3, 3, 3]}}

dict2 is

{726: {'sum_X': [8, 0, 2], 'sum_Y': [3, 2, 0]}, 128: {'sum_X': [0.5, 2, 0], 'sum_Y': [5, 3.5, 3]}}

Ожидаемый результат:

Union_dict =

{726: {'X': [3.5, 3.5, 2.0], 'Y': [2.0, 0.0, 0.0], 'chr': [2, 2, 2], 'sum_X': [8, 0, 2], 'sum_Y': [3, 2, 0]}, 128: {'X': [0.5, 4.0, 4.0], 'Y': [4.0, 3.5, 3.5], 'chr': [3, 3, 3], 'sum_X': [0.5, 2, 0], 'sum_Y': [5, 3.5, 3]}}

Каждый словарь имеет unique key (т.е. 726, 128...) и встречается в обоих словарях (dict1 and dict2), но каждый ключ в разных словарях имеет unique identifier с list values. Я хочу объединить эти словари, используя уникальные ключи, но также хочу сохранить порядок значений внутри списка нетронутым и упорядоченным.

Я пробовал несколько методов, включая расширенный метод в Как объединить два словаря в одно выражение? объясняется Aaron Hall. Я пытался изменить подходы, используя то, что я знаю о dict comprehension, но это не помогло.

Я старался:

  • 1

    union_dict = {k: [dict1[i] for i in v] for k, v in dict2.items()}
    
  • 2

    union_dict = defaultdict(dict)
    for a,b in dict1.items(), dict2.items():
        union_dict[dict1].append(dict2)
    
  • 3

    dicts = [dict1, dict2]
    union_dict = defaultdict(dict)
    for a,b in dicts:
        union_dict[k] = tuple(union_dict[k] for d in dicts)
    

Кроме того, не могли бы вы дать мне исчерпывающее объяснение нескольких способов сделать это и сохранить низкий объем памяти, поскольку мои словари будут довольно большими.

Спасибо большое !


person everestial007    schedule 14.03.2017    source источник
comment
[8, 0, 2}, это опечатка?   -  person Elmex80s    schedule 14.03.2017
comment
@ Elmex80s: да, это так. это должно быть [8, 0, 2].   -  person everestial007    schedule 14.03.2017
comment
@TemporalWolf: Извините, если это вас беспокоит. но я всегда пытаюсь решить проблему самостоятельно, используя то, что знаю, поваренную книгу и старые ответы на Stack Overflow. И, прибегать к помощи, когда тренировки считают бесполезными. Я надеюсь, вы понимаете. Спасибо !   -  person everestial007    schedule 14.03.2017
comment
Собственно, ничего для моего примера. Это только unique identifier, которые содержат list values в уникальном keys. Ключи одинаковы между двумя диктовками, но уникальный идентификатор - нет. Все, что я хочу, это union using the keys не что иное, как сохранение порядка значений в списке.   -  person everestial007    schedule 14.03.2017
comment
Основываясь на том, что я прочитал, update method должен работать, но не работает, если только я этого не понимаю.   -  person everestial007    schedule 14.03.2017
comment
гарантируется ли, что в обоих словарях не будет конкретного ключа?   -  person TemporalWolf    schedule 14.03.2017
comment
ключи будут в обоих словарях, но уникальный идентификатор списков не будет.   -  person everestial007    schedule 14.03.2017
comment
Не могли бы вы убрать флаг закрытия, если кто-то это сделал? Для закрытия нужно еще одно голосование, и я не хочу повторять еще одну проблему отсутствия ответа или повторной публикации.   -  person everestial007    schedule 14.03.2017


Ответы (1)


Примечание. Это решение возвращает результат как dict1:

for key, value in dict2.items():
    for subkey, subvalue in value.items():
        dict1[key][subkey] = subvalue

добавив все подразделы к dict1. Если есть конфликты (совпадающие подразделы, dict1s будут перезаписаны на dict2.

>>> dict1
{128: {'Y': [4.0, 3.5, 3.5], 'X': [0.5, 4.0, 4.0], 'chr': [3, 3, 3], 'sum_Y': [5, 3.5, 3], 'sum_X': [0.5, 2, 0]}, 
 726: {'Y': [2.0, 0.0, 0.0], 'X': [3.5, 3.5, 2.0], 'chr': [2, 2, 2], 'sum_Y': [3, 2, 0], 'sum_X': [8, 0, 2]}}

Если вы хотите сохранить dict1, просто используйте copy.deepcopy(), а затем добавьте к этому новому словарю.

person TemporalWolf    schedule 14.03.2017
comment
Это действительно простой, элегантный и всеобъемлющий. Спасибо большое ! - person everestial007; 15.03.2017