簡體   English   中英

Python。 如何減去2個字典

[英]Python. How to subtract 2 dictionaries

我有 2 個字典,A 和 B。A 有 700000 個鍵值對,B 有 560000 個鍵值對。 B 中的所有鍵值對都存在於 A 中,但 A 中的某些鍵是具有不同值的重復項,有些具有重復值但具有唯一鍵。 我想從 A 中減去 B,這樣我就可以得到剩下的 140000 個鍵值對。 當我根據鍵標識減去鍵值對時,由於重復鍵,我刪除了 150000 個鍵值對。 我想根據每個鍵值對的 BOTH 鍵和​​值的標識減去鍵值對,所以我得到 140000。歡迎提出任何建議。

這是一個例子:

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

我確實想得到:AB = {'10':1, '12':1, '10':2, '11':3}

我不想得到:

a) 基於密鑰時:

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

或者

b) 當基於值時:

{'11':3}

要獲取 A 中不在 B 中的項目,僅基於鍵:

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

要根據鍵和值獲取 A 中不在 B 中的項目:

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)

(與使用 map() 和A.pop ,如果 A 中不存在來自 B 的鍵,則使用 None 默認值調用A.pop不會中斷。此外,與使用all不同,此迭代器使用者將迭代所有值,而不管彈出值的真實性。)

一個簡單、直觀的方法是

dict(set(a.items()) - set(b.items()))
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(基於字典鍵):

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

另一種使用集合效率的方法。 可能@brien的答案更具多功能 他的回答非常好和簡潔,所以我贊成。

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

編輯:這里有一個假設,基於 OP 的問題,dict B 是 dict A 的子集,B 中的鍵/val 對在 A 中。如果您不嚴格使用,上面的代碼將產生意外結果鍵/值子集。 感謝史蒂文在他的評論中指出這一點。

因為我不能(還)評論:如果 B 中的某些鍵不存在於 A 中,則接受的答案將失敗。

使用帶有默認值的 dict.pop 會繞過它(借自How to remove a key from a Python dictionary? ):

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

或者

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

字典視圖

鍵視圖是類似設置的,因為它們的條目是唯一且可散列的。 如果所有值都是可散列的,因此 (key, value) 對是唯一且可散列的,則項目視圖也是類似設置的。 (值視圖不被視為類集合,因為條目通常不是唯一的。)對於類集合視圖,為抽象基類 collections.abc.Set 定義的所有操作都可用(例如,==、< , 或 ^)。

這樣你就可以:

>>> A = {'10':1, '11':1, '12':1, '10':2, '11':2, '11':3}
>>> B = {'11':1, '11':2}
>>> A.items() - B.items()
{('11', 3), ('12', 1), ('10', 2)}
>>> dict(A.items() - B.items())
{'11': 3, '12': 1, '10': 2}

對於 python 2 使用dict.viewitems

PS你不能在dict中有重復的鍵。

>>> A = {'10':1, '11':1, '12':1, '10':2, '11':2, '11':3}
>>> A
{'10': 2, '11': 3, '12': 1}
>>> B = {'11':1, '11':2}
>>> B
{'11': 2}
result = A.copy()
[result.pop(key) for key in B if B[key] == A[key]]

僅基於假設 A 是 B 的超集或 B 是 A 的子集的鍵:

Python 3:c = {k:a[k] for k in a.keys() - b.keys()}

Python 2:c = {k:a[k] for k in list(set(a.keys())-set(b.keys()))}

基於密鑰,也可用於更新就地@PaulMcG 答案

為了減去字典,你可以這樣做:

A.減(B)

注意:在 B 有 A 沒有的鍵的情況下,這會給你負值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM