2012-01-19 10 views
197

私は2つの既存の辞書を持っていて、もう1つは別の辞書に「追加」したいと思います。それによって、他の辞書のキー、値を最初の辞書にする必要があるということです。たとえば:辞書を辞書に追加しますか?

orig = { 
    'A': 1, 
    'B': 2, 
    'C': 3, 
} 

extra = { 
    'D': 4, 
    'E': 5, 
} 

dest = # something here involving orig and extra 

print dest 
{ 
    'A': 1, 
    'B': 2, 
    'C': 3, 
    'D': 4, 
    'E': 5 
} 

私はこのすべてがforループ(?多分)によって達成することができると思うが、辞書のいくつかの方法や私のためにこの仕事を保存し、他のモジュールがありますか?私が使用している実際の辞書は本当に大きいです...それはあなたがやりたいだろうよう

+15

いくつかの回答は 'orig.update(extra)'と指摘しています。 'extra'と' orig'に重複キーがある場合、最終値は 'extra'から取られることに注意してください。たとえば、 'd1 = {1:1,2:2}; d2 = {2: 'ha!'、3:3}; d1.update(d2) 'は' {1:1,2: 'ha!'、3:3} 'を含む' d1'になります。 –

答えて

310

あなたは

orig.update(extra) 

か、あなたはorigを変更したくない場合は、最初のコピーを作成する操作を行うことができます。

dest = dict(orig) # or orig.copy() 
dest.update(extra) 

注あれば、余分なとORIGキーが重複していること、最終的な価値は余分から取られる。たとえば、あなたがorigを変更したくないと仮定すると

>>> d1 = {1: 1, 2: 2} 
>>> d2 = {2: 'ha!', 3: 3} 
>>> d1.update(d2) 
>>> d1 
{1: 1, 2: 'ha!', 3: 3} 
+2

コピーメソッドのように浅いコピーを作成するdict.copy()があります。 – sleeplessnerd

+0

私は前にdict(** orig)イディオムを見ました。 dict(orig)に比べて何が利点ですか? – DSM

+2

'dict(** orig)'を使用すると、dictコンストラクタのキーワード引数として使用される新しい一時的なdictが作成されます。コンストラクタはこの引数の値をそれ自身にコピーします。したがって、 'dict(** orig)'で追加の辞書を作成します。元の質問のように、辞書が大きいときは無駄です。 –

12

dict.update()に見えます...おそらく

>> orig.update(extra) 
>>> orig 
{'A': 1, 'C': 3, 'B': 2, 'E': 5, 'D': 4} 
>>> 

、しかし、あなたは、元の辞書を更新する必要はありませんコピーではなく、仕事:

>>> dest = orig.copy() 
>>> dest.update(extra) 
>>> orig 
{'A': 1, 'C': 3, 'B': 2} 
>>> dest 
{'A': 1, 'C': 3, 'B': 2, 'E': 5, 'D': 4} 
5

.update()メソッドがあります:)

update([other]) 他のキー/値ペアで辞書を更新し、既存のキーを上書きします。戻り値なし。

update()は、別の辞書オブジェクトまたはキー/値ペアの繰り返し可能なもの(タプルまたは長さ2の他のiterable)を受け入れます。 キーワード引数が指定されている場合、辞書は のキー/値のペアd.update(赤= 1、青= 2)で更新されます。

バージョン2.4で変更されました:引数をキー/値ペアとキーワード引数の繰り返し可能にすることができました。

20

は、あなたが他の回答のようにコピーして更新を行うことができますか、あなたは両方の辞書からすべてのアイテムを渡すことで、ワンステップで新しい辞書を作成することができます

from itertools import chain 
dest = dict(chain(orig.items(), extra.items())) 

またはitertoolsなし:あなただけの結果を渡す必要が

dest = dict(list(orig.items()) + list(extra.items())) 

注dictのコンストラクタに0をPython 3のlist()に、2.xのdict.items()に既にリストを返します。dict(orig.items() + extra.items())を実行するだけです。より一般的なユースケースとして

、あなたは、単一の辞書に結合したいdictsの大きなリストを持って、あなたはこのような何かを行うことができます言う:

from itertools import chain 
dest = dict(chain.from_iterable(map(dict.items, list_of_dicts))) 
+1

実際には、 'SomeClass(** dict(args.items()+ {'special':a_value、})のように、同じ式で辞書を '更新'できます。) – carlosayam

5

私は与えたい答えがあります「collections.ChainMapを使用する」が、私はちょうどそれが唯一のPython 3.3で追加されたことを発見:https://docs.python.org/3.3/library/collections.html#chainmap-objects

あなたがが3.3ソースからクラスをベビーベッドしようとすることができます:ここではhttp://hg.python.org/cpython/file/3.3/Lib/collections/init.py#l763

が少ない機能、フルでありますPython 2.x compatib dict.mergeを使用して1つの辞書を別の辞書に展開/上書きするか、または両方をマージする追加のコピーを作成する代わりに、両方を順番に検索する検索チェーンを作成します。折り返すマッピングを複製しないため、ChainMapはメモリをほとんど使用せず、後ですべてのサブマッピングを変更することができます。注文が重要であるため、チェーンを使用してデフォルトを設定することもできます(つまり、ユーザー設定> config> env)。また、問題によっては多分、解決するために

dest = {**orig, **extra} 

dest = {**orig, 'D': 4, 'E': 5} 
17

これを実現するための最も神託(とわずかに速い)方法があります

dest = {} 
dest.update(orig) 
dest.update(extra) 

これで新しい辞書destが作成されます修正するorigおよびextraを使用してください。

注:キーの値がorigextraの場合、extraorigを上書きします。

+2

悲しいことに、2.xではうまくいきません。((3.xの場合のみ – madjardi

+1

dict(itertools.chain(d.items()、y.items())) – madjardi

+0

どちらのバージョンでも、 3.x IDLEの構文エラー – Noumenon

0

3-ライナーを組み合わせることにより、

+0

Python 2とPython 3の両方で動作します。 – jkdev

関連する問題