Как объединить несколько кодов с одним и тем же ключом? - PullRequest
50 голосов
/ 10 мая 2011

У меня есть несколько пар «ключ / значение», как это:

d1 = {key1: x1, key2: y1}  
d2 = {key1: x2, key2: y2}  

Я хочу, чтобы результатом был новый дикт (наиболее эффективным способом, если это возможно):

d = {key1: (x1, x2), key2: (y1, y2)}  

На самом деле, я хочу, чтобы результат d был:

d = {key1: (x1.x1attrib, x2.x2attrib), key2: (y1.y1attrib, y2.y2attrib)}  

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

Ответы [ 8 ]

51 голосов
/ 10 мая 2011

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

from collections import defaultdict

d1 = {1: 2, 3: 4}
d2 = {1: 6, 3: 7}

dd = defaultdict(list)

for d in (d1, d2): # you can list as many input dicts as you want here
    for key, value in d.iteritems():
        dd[key].append(value)

print(dd)

Показывает:

defaultdict(<type 'list'>, {1: [2, 6], 3: [4, 7]})

Кроме того, чтобы получить .attrib, просто измените append(value) на append(value.attrib)

17 голосов
/ 10 мая 2011

при условии, что все ключи всегда присутствуют во всех диктовках:

ds = [d1, d2]
d = {}
for k in d1.iterkeys():
    d[k] = tuple(d[k] for d in ds)

Примечание: в Python 3.x используйте код ниже:

ds = [d1, d2]
d = {}
for k in d1.keys():
  d[k] = tuple(d[k] for d in ds)

и если в файле содержатся пустые массивы:

ds = [d1, d2]
d = {}
for k in d1.keys():
  d[k] = np.concatenate(list(d[k] for d in ds))
3 голосов
/ 10 мая 2011

Если у вас есть только d1 и d2,

from collections import defaultdict

d = defaultdict(list)
for a, b in d1.items() + d2.items():
    d[a].append(b)
2 голосов
/ 12 января 2018
dict1 = {'m': 2, 'n': 4}
dict2 = {'n': 3, 'm': 1}

Убедившись, что ключи в том же порядке:

dict2_sorted = {i:dict2[i] for i in dict1.keys()}

keys = dict1.keys()
values = zip(dict1.values(), dict2_sorted.values())
dictionary = dict(zip(keys, values))

дает:

{'m': (2, 1), 'n': (4, 3)}
2 голосов
/ 10 мая 2011

Вот один из подходов, который вы можете использовать, который будет работать, даже если у обоих дикторов нет одинаковых клавиш:

d1 = {'a':'test','b':'btest','d':'dreg'}
d2 = {'a':'cool','b':'main','c':'clear'}

d = {}

for key in set(d1.keys() + d2.keys()):
    try:
        d.setdefault(key,[]).append(d1[key])        
    except KeyError:
        pass

    try:
        d.setdefault(key,[]).append(d2[key])          
    except KeyError:
        pass

print d

Это будет генерировать ниже ввода:

{'a': ['test', 'cool'], 'c': ['clear'], 'b': ['btest', 'main'], 'd': ['dreg']}
0 голосов
/ 22 августа 2017

Обновление Python 3.x

От Эли Бендерского ответ:

В Python 3 удалены dict.iteritems, вместо них используется dict.items.Смотрите Python вики: https://wiki.python.org/moin/Python3.0

from collections import defaultdict

dd = defaultdict(list)

for d in (d1, d2):
    for key, value in d.items():
        dd[key].append(value)
0 голосов
/ 29 января 2017

Компактная возможность

d1={'a':1,'b':2}
d2={'c':3,'d':4}
context={**d1, **d2}
context
{'b': 2, 'c': 3, 'd': 4, 'a': 1}
0 голосов
/ 10 мая 2011
def merge(d1, d2, merge):
    result = dict(d1)
    for k,v in d2.iteritems():
        if k in result:
            result[k] = merge(result[k], v)
        else:
            result[k] = v
    return result

d1 = {'a': 1, 'b': 2}
d2 = {'a': 1, 'b': 3, 'c': 2}
print merge(d1, d2, lambda x, y:(x,y))

{'a': (1, 1), 'c': 2, 'b': (2, 3)}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...