2012-05-17 4 views
8

У меня есть словарь python dict1 с более чем 20 000 ключами, и я хочу, чтобы update с другим словарем dict2. Словари выглядеть следующим образом:Вставить или обновить ключи в словаре python

dict1 
    key11=>[value11] 
    key12=>[value12] 
    ... 
    ... 
    keyxyz=>[value1x]  //common key 
    ...... so on 

dict2 
    key21=>[value21] 
    key22=>[value22] 
    ... 
    ... 
    keyxyz=>[value2x]  // common key 
    ........ so on 

Если я использую

dict1.update(dict2) 

затем ключи dict1, которые аналогичны клавишам dict2 будут иметь свои значения перезаписаны значениями dict2. Я хочу, если ключ уже присутствует в dict1, тогда значение этого ключа в dict2 должно быть добавлено к значению dict1. Так

dict1.conditionalUpdate(dict2) 

должно привести к

dict1 
    key11=>[value11] 
    key12=>[value12] 
    key21=>[value21] 
    key22=>[value22] 
    ... 
    ... 
    keyxyz=>[value1x,value2x] 

Наивный метод будет итерация ключи dict2 для каждого ключа dict1 и вставить или ключи обновления. Есть ли лучший метод? Поддерживает ли python встроенную структуру данных, поддерживающую такую ​​функциональность?

+0

Вот решение уже поставленного вопроса. http://stackoverflow.com/questions/38987/how-can-i-merge-two-python-dictionaries-as-a-single-expression – ronyswag

+0

@ronyswag Это не тот же вопрос. –

ответ

9

Используйте defaultdict из модуля коллекций.

>>> from collections import defaultdict 
>>> dict1 = {1:'a',2:'b',3:'c'} 
>>> dict2 = {1:'hello', 4:'four', 5:'five'} 
>>> my_dict = defaultdict(list) 
>>> for k in dict1: 
... my_dict[k].append(dict1[k]) 
... 
>>> for k in dict2: 
... my_dict[k].append(dict2[k]) 
... 
>>> my_dict[1] 
['a', 'hello'] 
+1

Правильно. Фактически, если вы просматриваете документы Python, есть пример, который почти соответствует тому, что вы просите - http://docs.python.org/library/collections.html#defaultdict-examples –

1

Это на самом деле очень просто сделать с помощью Dict понимания и itertools.groupby():

dict1 = {1: 1, 2: 2, 3: 3, 4: 4} 
dict2 = {5: 6, 7: 8, 1: 1, 2: 2} 

from itertools import groupby, chain 
from operator import itemgetter 

sorted_items = sorted(chain(dict1.items(), dict2.items())) 

print({key: [value[1] for value in values] for key, values in groupby(sorted_items, itemgetter(0))}) 

дает нам:

{1: [1, 1], 2: [2, 2], 3: [3], 4: [4], 5: [6], 7: [8]} 

Естественно, это создает новый Dict, но если вы потребность в обновите первый dict, вы можете сделать это тривиально, обновив новый. Если ваши значения уже являются списками, для этого может потребоваться незначительная модификация (но я полагаю, что вы делали это ради операции, и в этом случае нет необходимости).

Естественно, если вы используете Python 2.x, то вы захотите использовать dict.viewitems() или dict.iteritems() над dict.items(). Если вы используете версию Python до понимания dict, тогда вместо этого вы можете использовать dict((key , value) for ...).

0

Другой метод, не импортируя ничего, только с обычный словарь Python:

>>> dict1 = {1:'a',2:'b',3:'c'} 
>>> dict2 = {1:'hello', 4:'four', 5:'five'} 
>>> for k in dict2: 
... dict1[k] = dict1.get(k,"") + dict2.get(k) 
... 
>>> dict1 
{1: 'ahello', 2: 'b', 3: 'c', 4: 'four', 5: 'five'} 
>>> 

dict1.get(k,"") возвращает значение, связанное с k, если она существует, или пустая строка, в противном случае, а затем добавить содержимое dict2 ,