web-dev-qa-db-ja.com

同じキーで複数の辞書をマージする方法は?

このような複数の辞書/キーと値のペアがあります:

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)}  

誰かが私に最初の結果を得る方法を教えてくれたら、残りを理解することができます。

52
Salil

すべてのキーがすべての辞書に常に存在すると仮定すると:

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)

また、dicにnumpy配列が含まれる場合:

ds = [d1, d2]
d = {}
for k in d1.keys():
  d[k] = np.concatenate(list(d[k] for d in ds))
18
blubb

以下は、キーが一部の辞書にしか含まれていない場合に、任意の量の辞書を処理する一般的なソリューションです。

_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)に変更するだけです

52
Eli Bendersky

D1とd2しかない場合

from collections import defaultdict

d = defaultdict(list)
for a, b in d1.items() + d2.items():
    d[a].append(b)
4
riza
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)}
3
Mahdi Ghelichi

両方のディクショナリに同じキーがない場合でも機能する1つのアプローチを次に示します。

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']}
2
sateesh

Python 3.xアップデート

Eli Benderskyの回答から:

Python 3はdict.iteritemsを削除し、代わりにdict.itemsを使用します。 Python wiki: https://wiki.python.org/moin/Python3. を参照してください。

from collections import defaultdict

dd = defaultdict(list)

for d in (d1, d2):
    for key, value in d.items():
        dd[key].append(value)
0
candid
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)}
0
ralphtheninja

2リストのソリューションを補足するために、singleリストを処理するソリューションを以下に示します。

サンプルリスト(NetworkX関連。読みやすいようにここで手動でフォーマット):

ec_num_list = [((src, tgt), ec_num['ec_num']) for src, tgt, ec_num in G.edges(data=True)]

print('\nec_num_list:\n{}'.format(ec_num_list))
ec_num_list:
[((82, 433), '1.1.1.1'),
  ((82, 433), '1.1.1.2'),
  ((22, 182), '1.1.1.27'),
  ((22, 3785), '1.2.4.1'),
  ((22, 36), '6.4.1.1'),
  ((145, 36), '1.1.1.37'),
  ((36, 154), '2.3.3.1'),
  ((36, 154), '2.3.3.8'),
  ((36, 72), '4.1.1.32'),
  ...] 

同じタプル(タプルで定義)の重複値に注意してください。これらの「値」を対応する「キー」と照合するには:

from collections import defaultdict
ec_num_collection = defaultdict(list)
for k, v in ec_num_list:
    ec_num_collection[k].append(v)

print('\nec_num_collection:\n{}'.format(ec_num_collection.items()))
ec_num_collection:
[((82, 433), ['1.1.1.1', '1.1.1.2']),   ## << grouped "values"
((22, 182), ['1.1.1.27']),
((22, 3785), ['1.2.4.1']),
((22, 36), ['6.4.1.1']),
((145, 36), ['1.1.1.37']),
((36, 154), ['2.3.3.1', '2.3.3.8']),    ## << grouped "values"
((36, 72), ['4.1.1.32']),
...] 

必要に応じて、そのリストをdictに変換します:

ec_num_collection_dict = {k:v for k, v in Zip(ec_num_collection, ec_num_collection)}

print('\nec_num_collection_dict:\n{}'.format(dict(ec_num_collection)))
  ec_num_collection_dict:
  {(82, 433): ['1.1.1.1', '1.1.1.2'],
  (22, 182): ['1.1.1.27'],
  (22, 3785): ['1.2.4.1'],
  (22, 36): ['6.4.1.1'],
  (145, 36): ['1.1.1.37'],
  (36, 154): ['2.3.3.1', '2.3.3.8'],
  (36, 72): ['4.1.1.32'],
  ...}

参考文献

0
Victoria Stuart