web-dev-qa-db-ja.com

Python。 2つの辞書を引く方法

AとBの2つの辞書があります。Aには700000のキーと値のペアがあり、Bには560000のキーと値のペアがあります。 Bのすべてのキーと値のペアがAに存在しますが、Aの一部のキーは異なる値で重複しており、一部のキーは重複した値ですが一意のキーです。 AからBを減算して、残りの140000個のキーと値のペアを取得できるようにします。キーIDに基づいてキーと値のペアを減算する場合、キーが繰り返されるため、たとえば150000個のキーと値のペアを削除します。各キーと値のペアの両方のキーと値のIDに基づいてキーと値のペアを減算したいので、140000を取得します。どんな提案でも歓迎します。

これは例です:

A = {'10':1, '11':1, '12':1, '10':2, '11':2, '11':3}
B = {'11':1, '11':2}

取得したい:A-B = {'10':1、'12 ':1、'10':2、'11 ':3}

私は取得したくない:

a)キーに基づく場合:

{'10':1, '12':1, '10':2}

または

b)値に基づく場合:

{'11':3}
6
Lucas
A = {'10':1, '11':1, '12':1, '10':2, '11':2, '11':3}
B = {'11':1, '11':2}

Pythonで重複するキーを持つことはできません。上記を実行すると、次のようになります。

A={'11': 3, '10': 2, '12': 1}
B={'11': 2}

しかし、あなたの質問に答えるために、A-B(dictキーに基づく)を行うには:

all(map( A.pop, B))   # use all() so it works for Python 2 and 3.
print A # {'10': 2, '12': 1}
6

キーだけに基づいて、BにないアイテムをAに取得するには:

C = {k:v for k,v in A.items() if k not in B}

キーと値に基づいて、BにないAのアイテムを取得するには:

C = {k:v for k,v in A.items() if k not in B or v != B[k]}

Aを適切に更新するには(A -= Bのように)、次のようにします。

from collections import deque
consume = deque(maxlen=0).extend
consume(A.pop(key, None) for key in B)

A.popでmap()を使用するのとは異なり、デフォルトでNoneを指定してA.popを呼び出すと、BのキーがAに存在しない場合でも壊れません。また、allの使用とは異なり、このイテレータ消費者は、ポップされた値の真実性に関係なく、すべての値を繰り返し処理します。)

24
PaulMcG

これを行う簡単で直感的な方法は次のとおりです。

dict(set(a.items()) - set(b.items()))
13
Brien

セットの効率を使用する別の方法。このmightは、 @ brien による回答よりも多目的である可能性があります。彼の答えはとても素晴らしく簡潔なので、私はそれを支持しました。

diffKeys = set(a.keys()) - set(b.keys())
c = dict()
for key in diffKeys:
  c[key] = a.get(key)

編集:ここでは、OPの質問に基づいて、dictBはdictAのサブセットであり、Bのキー/値のペアはAにあるという仮定があります。上記のコードは、厳密に作業していない場合、予期しない結果になります。キー/値のサブセット。コメントでこれを指摘してくれたスティーブンに感謝します。

3
robert arles

私は(まだ)コメントできないので:受け入れられた answer は、Aに存在しないBにいくつかのキーがある場合に失敗します。

デフォルトでdict.popを使用すると、それを回避できます( Python辞書? からキーを削除する方法)から借用):

all(A.pop(k, None) for k in B)

または

Tuple(A.pop(k, None) for k in B)
2
slavos1
result = A.copy()
[result.pop(key) for key in B if B[key] == A[key]]
1
zondo