web-dev-qa-db-ja.com

2つの辞書を連結してPythonで新しい辞書を作成する方法は?

3つの辞書があるとしましょう

d1={1:2,3:4}
d2={5:6,7:9}
d3={10:8,13:22}

これら3つの辞書を組み合わせた新しいd4を作成するにはどうすればよいですか?すなわち:

d4={1:2,3:4,5:6,7:9,10:8,13:22}
194
timy
  1. 最も遅く、Python3では動作しません:itemsを連結し、結果のリストでdictを呼び出します:

    $ python -mtimeit -s'd1={1:2,3:4}; d2={5:6,7:9}; d3={10:8,13:22}' \
    'd4 = dict(d1.items() + d2.items() + d3.items())'
    
    100000 loops, best of 3: 4.93 usec per loop
    
  2. 最速:dictコンストラクターをヒルトに活用してから、1つのupdate

    $ python -mtimeit -s'd1={1:2,3:4}; d2={5:6,7:9}; d3={10:8,13:22}' \
    'd4 = dict(d1, **d2); d4.update(d3)'
    
    1000000 loops, best of 3: 1.88 usec per loop
    
  3. 中間:updateのループは、最初は空のdictを呼び出します:

    $ python -mtimeit -s'd1={1:2,3:4}; d2={5:6,7:9}; d3={10:8,13:22}' \
    'd4 = {}' 'for d in (d1, d2, d3): d4.update(d)'
    
    100000 loops, best of 3: 2.67 usec per loop
    
  4. または、同等に、1つのコピーアクターと2つの更新:

    $ python -mtimeit -s'd1={1:2,3:4}; d2={5:6,7:9}; d3={10:8,13:22}' \
    'd4 = dict(d1)' 'for d in (d2, d3): d4.update(d)'
    
    100000 loops, best of 3: 2.65 usec per loop
    

アプローチ(2)をお勧めします。特に、(1)を回避することをお勧めします(アイテムの連結リストの一時データ構造にO(N)余分な補助メモリも占有します)。

233
Alex Martelli
d4 = dict(d1.items() + d2.items() + d3.items())

代わりに(そしておそらく高速):

d4 = dict(d1)
d4.update(d2)
d4.update(d3)

前のSOの質問は、これらの両方の回答が here から来たものです。

102
Amber

update() メソッドを使用して、すべてのアイテムを含む新しい辞書を作成できます。

dall = {}
dall.update(d1)
dall.update(d2)
dall.update(d3)

または、ループ内:

dall = {}
for d in [d1, d2, d3]:
  dall.update(d)
52
sth

Dictコンストラクターを使用する

d1={1:2,3:4}
d2={5:6,7:9}
d3={10:8,13:22}

d4 = reduce(lambda x,y: dict(x, **y), (d1, d2, d3))

機能として

from functools import partial
dict_merge = partial(reduce, lambda a,b: dict(a, **b))

dict.update()メソッドを使用すると、中間辞書を作成するオーバーヘッドを排除できます。

from functools import reduce
def update(d, other): d.update(other); return d
d4 = reduce(update, (d1, d2, d3), {})

N個の辞書を連結するために簡単に一般化できる1行(importsはカウントしない)です:

Python 2.6以降

from itertools import chain
dict(chain.from_iterable(d.iteritems() for d in (d1, d2, d3))

出力:

>>> from itertools import chain
>>> d1={1:2,3:4}
>>> d2={5:6,7:9}
>>> d3={10:8,13:22}
>>> dict(chain.from_iterable(d.iteritems() for d in (d1, d2, d3)))
{1: 2, 3: 4, 5: 6, 7: 9, 10: 8, 13: 22}

N個のディクテーションを連結するために一般化:

from itertools import chain
def dict_union(*args):
    return dict(chain.from_iterable(d.iteritems() for d in args))

Python 3

from itertools import chain
dict(chain.from_iterable(d.items() for d in (d1, d2, d3)))

そして:

from itertools import chain
def dict_union(*args):
    return dict(chain.from_iterable(d.items() for d in args))

私はこのパーティーに少し遅れていますが、私は知っていますが、これが誰かを助けることを願っています。

21
ron rothman