Pythonは辞書の「拡張」


463

辞書を別の辞書で拡張する最良の方法はどれですか?例えば:

>>> a = { "a" : 1, "b" : 2 }
>>> b = { "c" : 3, "d" : 4 }
>>> a
{'a': 1, 'b': 2}
>>> b
{'c': 3, 'd': 4}

私はこの回避forループを取得するための操作を探しています:

{ "a" : 1, "b" : 2, "c" : 3, "d" : 4 }

私は次のようなことをしたいです:

a.extend(b)  # This does not work

25
私はリストについて知っていました[]、それから私は他の人のために働くかもしれないと思いますextrangeではありません;-)
FerranB 2009

回答:


695

6
ドキュメントを読んだ後、「更新」はあるが「拡張」がない理由が理解できます。
georg、2014

58
update()はdictを直接変更し、Noneを返すことに注意してください。
e18r

5
しかし、まだ定義されていない(つまり、既存の値を上書きしない)値で辞書を拡張したい場合はどうでしょうか?たとえば、dict {"a":2, "b":3}をdict {"b":4, "c":5}に更新してdict をdict {"a":2, "b":3,"c":5}?もちろん、update()何かを動かして使用することも可能ですが、1行で実行できればもっと良いでしょう...
Nearoo

17
@Nearoo-単に反対の方法で更新します。x.update(y)[xの値をyで上書きする]の代わりに、y.update(x)[これはyの値をxで上書きする]を使用し、yを選択したディクテーションとして使用して以降の操作を行う
jonathanl

update静かに既存のエントリを上書きすることに注意してください。つまり、の値はすべて、重複するキーの値をb上書きしaます。
CGFoX

186

この閉じた質問の美しい宝石:

どちらの入力ディクテーションも変更しない「oneliner way」は、

basket = dict(basket_one, **basket_two)

ここで**basket_two**)の意味を学びます

競合する場合は、のアイテムがのアイテムbasket_twoをオーバーライドしますbasket_one。ワンライナーが進むにつれ、これはかなり読みやすく、透過的です。他の2つを組み合わせた辞書が便利になるときはいつでも、私はそれを使用することに対して何の責任もありません(実際にそれを理解できない読者は、これが彼と彼女にdict**フォームとフォームについて学ぶように促す方法;-)。したがって、たとえば、次のように使用します。

x = mungesomedict(dict(adict, **anotherdict))

私のコードでかなり頻繁に発生します。

Alex Martelliが最初に提出

注: Python 3では、これは、basket_twoのすべてのキーがである場合にのみ機能しstringます。


3
のドキュメントdictは簡単に見つけることができます**が、少しトリッキーです(キーワードはkwargsです)。ここで素敵な説明は次のとおりです。saltycrane.com/blog/2008/01/...
johndodo

4
これは、単一のコマンドで2番目の変数を生成するために使用できますがbasket_one.update(<dict>)、名前が示すように、既存の辞書(または複製された辞書)を更新します。
風鈴14年

2
Python 3では、引数名、つまりのキーは**anotherdict文字列でなければならないことに注意してください。
Petr Viktorin 2014

ありがとう@johndodo-私はあなたの提案を投稿に統合しました。
トムレイズ2016年

1
受け入れられた回答に対する機能的な代替案。このアプローチは、新しく組み合わされた辞書を直接使用する必要がある場合に適しています。(承認された回答に関する@ e18rのコメントも参照してください)。
chinnychinchin

45

辞書マッピングで辞書内包を使用してみましたか?

a = {'a': 1, 'b': 2}
b = {'c': 3, 'd': 4}

c = {**a, **b}
# c = {"a": 1, "b": 2, "c": 3, "d": 4}

別の方法は、dict(iterable、** kwarg)を使用することです

c = dict(a, **b)
# c = {'a': 1, 'b': 2, 'c': 3, 'd': 4}

Python 3.9では、union |を使用して2つのdictを追加できます。オペレーター

# use the merging operator |
c = a | b
# c = {'a': 1, 'b': 2, 'c': 3, 'd': 4}

5
参考:これはPython 2.7の有効な構文ではありません
Asav Patel

2
この構文はかなり新しい(Python 3.5)
pianoJames

24
a.update(b)

キーと値をbからaに追加しすでにキーの値がある場合は上書きします。


17

他の人が、述べたようにa.update(b)、いくつかのdictsのためにab、あなたの質問にを求めてきた結果を実現します。ただし、extendマッピング/セットオブジェクトのメソッドが構文a.extend(b)aの値をの値で上書きしないことを望んでいることを何度も見たことがあることを指摘したいと思いbます。a.update(b)a値を上書きするため、には適していませんextend

一部の言語では、このメソッドdefaultsまたはを呼び出します。これinjectは、既存の値を上書きせずにbの値(デフォルト値のセットである場合があります)をディクショナリに注入する方法と考えることができるためです。

もちろん、a.extend(b)とほぼ同じように簡単にメモできますb.update(a); a=b。割り当てを削除するには、次のようにします。

def extend(a,b):
    """Create a new dictionary with a's properties extended by b,
    without overwriting.

    >>> extend({'a':1,'b':2},{'b':3,'c':4})
    {'a': 1, 'c': 4, 'b': 2}
    """
    return dict(b,**a)

の副作用のないdictコンストラクターを使用したスマートなアイデアを提供してくれたTom Leysに感謝しextendます。


1

Python 3.3で導入されたPython のcollections.Chainmapを使用することもできます。

from collections import Chainmap
c = Chainmap(a, b)
c['a'] # returns 1

これには、ユースケースに応じて、いくつかの利点があります。これらについてはここで詳しく説明しますが、簡単な概要を説明します。

  • チェーンマップは辞書のビューのみを使用するため、データは実際にはコピーされません。これにより、チェーンが速くなります(ただし、ルックアップが遅くなります)。
  • キーが実際に上書きされることはないため、必要に応じて、データがaからのものかbからのものかがわかります。

これは主に、設定辞書などに役立ちます。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.