辞書は、Python 言語の唯一のマッピング タイプです。次の記事では、Python で 2 つの辞書 (dict) をエレガントに結合する方法について主に説明します。コードが詳しく紹介されていますので、必要な方はぜひ参考にしてみてください。
はじめに
Dictionary は Python の最も強力なデータ型の 1 つです。この記事では、2 つの辞書 (dict) を結合する Python の関連コンテンツを詳しく紹介し、参考と学習のために共有します。では、詳しい紹介を見てみましょう。
2つの辞書をマージする1行のコード
2つの辞書xとyがあると仮定し、xとyの値を変更せずにそれらを新しい辞書にマージします。たとえば
x = {'a': 1, 'b': 2} y = {'b': 3, 'c': 4}
新しい Z の結果が得られることを期待します。キーが同じであれば、y は x をカバーします。期待される結果は次のとおりです
>>> z {'a': 1, 'b': 3, 'c': 4}
PEP448 では、実装できる新しい構文があり、この構文は python3.5 でサポートされています。マージされたコードは次のとおりです
z = {**x, **y}
適切なコード行。 多くの人がまだ python2 を使用しているため、python2 および python3.0 ~ python3.4 を使用している人には、より洗練された方法がありますが、それには 2 行のコードが必要です。
z = x.copy() z.update(y)
上記の方法では、yがxの内容を上書きするので、最終的な結果はb=3になります
python3.5を使わずに一行で完成させる方法
If Python 3.5 をまだ使用したことがない場合、または下位互換性のあるコードを作成する必要があり、それを単一の式で実行したい場合、最も効率的な方法は、それを関数に入れることです:
def merge_two_dicts(x, y): """Given two dicts, merge them into a new dict as a shallow copy.""" z = x.copy() z.update(y) return z
次に、1 行のコードを記述します。呼び出しを完了します:
z = merge_two_dicts(x, y)
def merge_dicts(*dict_args): """ Given any number of dicts, shallow copy and merge into a new dict, precedence goes to key value pairs in latter dicts. """ result = {} for dictionary in dict_args: result.update(dictionary) return result
など、複数の辞書をマージする関数を定義することもできます。その後、次のように使用できます
z = merge_dicts(a, b, c, d, e, f, g)
それらのすべてで同じキー前回のものをカバーします。
あまりエレガントではないデモ
items
この方法を使用する人もいます:
z = dict(x.items() + y.items())
これは実際にメモリ内に 2 つのリストを作成し、その後 3 番目のリストを作成します。コピーが完了したら、新しい辞書を作成し、最初の 3 つのリストを削除します。このメソッドはパフォーマンスを消費し、Python3 では items() がオブジェクトを返すため、これを正常に実行できません。
>>> c = dict(a.items() + b.items()) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unsupported operand type(s) for +: 'dict_items' and 'dict_items'
z = dict(list(x.items()) + list(y.items()))
のように明示的にリストにキャストする必要があります。これはあまりにも無駄なパフォーマンスです。 さらに、 items()
によって返されるリストに基づく Union メソッドも python3 では失敗します。さらに、union メソッドは繰り返される key の値に不確実性をもたらすため、優先順位の要件がある場合に使用します。 2 つの辞書をマージする場合、この方法はまったく不適切です。 z = dict(list(x.items()) + list(y.items()))
,这太浪费性能了。 另外,想以来于items()
返回的list做并集的方法对于python3来说也会失败,而且,并集的方法,导致了重复的key在取值时的不确定,所以,如果你对两个dict合并有优先级的要求,这个方法就彻底不合适了。
>>> x = {'a': []} >>> y = {'b': []} >>> dict(x.items() | y.items()) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unhashable type: 'list'
这里有一个例子,其中y应该具有优先权,但是由于任意的集合顺序,x的值被保留:
>>> x = {'a': 2} >>> y = {'a': 1} >>> dict(x.items() | y.items()) {'a': 2}
构造函数
也有人会这么用
z = dict(x, **y)
这样用很好,比前面的两步的方法高效多了,但是可阅读性差,不够pythonic,如果当key不是字符串的时候,python3中还是运行失败
>>> c = dict(a, **b) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: keyword arguments must be strings
Guido van Rossum 大神说了:宣告dict({}, {1:3})
{k: v for d in dicts for k, v in d.items()}
ここでは y が優先される例を示しますが、任意の順序で設定されているため、
dict((k, v) for d in dicts for k, v in d.items())の値は、前の 2 つのステップよりも非常に簡単です。メソッドですが、可読性が低く、Python 性が十分ではありません。キーが文字列でない場合は、やはり python3 での実行に失敗します
import itertools z = dict(itertools.chain(x.iteritems(), y.iteritems()))Guido Master van Rossum は次のように述べています:
dict({}, {1:3})
は、結局のところメカニズムの悪用であるため、違法です。この方法はよりハック的ではありますが、あまりにもご都合主義的です。
パフォーマンスは低いがよりエレガントないくつかのメソッド
以下のメソッドは、パフォーマンスは低いですが、items メソッドよりもはるかに優れています。そして優先順位をサポートします。
>>> min(timeit.repeat(lambda: merge_two_dicts(x, y)))
0.5726828575134277
>>> min(timeit.repeat(lambda: {k: v for d in (x, y) for k, v in d.items()} ))
1.163769006729126
>>> min(timeit.repeat(lambda: dict(itertools.chain(x.iteritems(),y.iteritems()))))
1.1614501476287842
>>> min(timeit.repeat(lambda: dict((k, v) for d in (x, y) for k, v in d.items())))
2.2345519065856934
Python2.6 では、これを行うことができます
>>> min(timeit.repeat(lambda: {**x, **y})) 0.4094954460160807 >>> min(timeit.repeat(lambda: merge_two_dicts(x, y))) 0.7881555100320838 >>> min(timeit.repeat(lambda: {k: v for d in (x, y) for k, v in d.items()} )) 1.4525277839857154 >>> min(timeit.repeat(lambda: dict(itertools.chain(x.items(), y.items())))) 2.3143140770262107 >>> min(timeit.repeat(lambda: dict((k, v) for d in (x, y) for k, v in d.items()))) 3.2069112799945287itertools.chain は、キーと値のペアのイテレータを正しい順序でチェーンします:
rrreee
パフォーマンス テスト
以下は、Python 2.7 (システム Python) の Ubuntu 14.04 で実行されました。
以上がPython で 2 つの辞書を結合する方法の例を共有するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。