Python。如何减去2个字典
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35187165/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python. How to subtract 2 dictionaries
提问by Lucas
I have 2 dictionaries, A and B. A has 700000 key-value pairs and B has 560000 key-values pairs. All key-value pairs from B are present in A, but some keys in A are duplicates with different values and some have duplicated values but unique keys. I would like to subtract B from A, so I can get the remaining 140000 key-value pairs. When I subtract key-value pairs based on key identity, I remove lets say 150000 key-value pairs because of the repeated keys. I want to subtract key-value pairs based on the identity of BOTH key AND value for each key-value pair, so I get 140000. Any suggestion would be welcome.
我有 2 个字典,A 和 B。A 有 700000 个键值对,B 有 560000 个键值对。B 中的所有键值对都存在于 A 中,但 A 中的某些键是具有不同值的重复项,有些具有重复值但具有唯一键。我想从 A 中减去 B,这样我就可以得到剩下的 140000 个键值对。当我根据键标识减去键值对时,由于重复键,我删除了 150000 个键值对。我想根据每个键值对的 BOTH 键和值的标识减去键值对,所以我得到 140000。欢迎提出任何建议。
This is an example:
这是一个例子:
A = {'10':1, '11':1, '12':1, '10':2, '11':2, '11':3}
B = {'11':1, '11':2}
I DO want to get: A-B = {'10':1, '12':1, '10':2, '11':3}
我确实想得到:AB = {'10':1, '12':1, '10':2, '11':3}
I DO NOT want to get:
我不想得到:
a) When based on keys:
a) 基于密钥时:
{'10':1, '12':1, '10':2}
or
或者
b) When based on values:
b) 当基于值时:
{'11':3}
采纳答案by Monty Montemayor
A = {'10':1, '11':1, '12':1, '10':2, '11':2, '11':3}
B = {'11':1, '11':2}
You can't have duplicate keys in Python. If you run the above, it will get reduced to:
在 Python 中不能有重复的键。如果你运行上面的,它会减少到:
A={'11': 3, '10': 2, '12': 1}
B={'11': 2}
But to answer you question, to do A - B (based on dict keys):
但要回答你的问题,做 A - B(基于字典键):
all(map( A.pop, B)) # use all() so it works for Python 2 and 3.
print A # {'10': 2, '12': 1}
回答by zondo
result = A.copy()
[result.pop(key) for key in B if B[key] == A[key]]
回答by PaulMcG
To get items in A that are not in B, based just on key:
要获取 A 中不在 B 中的项目,仅基于键:
C = {k:v for k,v in A.items() if k not in B}
To get items in A that are not in B, based on key and value:
要根据键和值获取 A 中不在 B 中的项目:
C = {k:v for k,v in A.items() if k not in B or v != B[k]}
To update A in place (as in A -= B
) do:
要就地更新 A(如A -= B
),请执行以下操作:
from collections import deque
consume = deque(maxlen=0).extend
consume(A.pop(key, None) for key in B)
(Unlike using map() with A.pop
, calling A.pop
with a None default will not break if a key from B is not present in A. Also, unlike using all
, this iterator consumer will iterate over all values, regardless of truthiness of the popped values.)
(与使用 map() with 不同A.pop
,A.pop
如果 A 中不存在来自 B 的键,则使用 None 默认调用不会中断。此外,与 using 不同all
,此迭代器使用者将迭代所有值,而不管弹出值的真实性如何。)
回答by Brien
An easy, intuitive way to do this is
一个简单、直观的方法是
dict(set(a.items()) - set(b.items()))
回答by robert arles
Another way of using the efficiency of sets. This mightbe more multipurpose than the answer by @brien. His answer is very nice and concise, so I upvoted it.
另一种使用集合效率的方法。这可能比@brien的答案更具多功能性。他的回答非常好和简洁,所以我赞成。
diffKeys = set(a.keys()) - set(b.keys())
c = dict()
for key in diffKeys:
c[key] = a.get(key)
EDIT: There is the assumption here, based on the OP's question, that dict B is a subset of dict A, that the key/val pairs in B are in A. The above code will have unexpected results if you are not working strictly with a key/val subset. Thanks to Steven for pointing this out in his comment.
编辑:这里有一个假设,基于 OP 的问题,dict B 是 dict A 的子集,B 中的键/val 对在 A 中。如果您不严格使用,上面的代码将产生意外结果键/值子集。感谢史蒂文在他的评论中指出这一点。
回答by Rupin Talreja
Based on only keys assuming A is a superset of B or B is a subset of A:
仅基于假设 A 是 B 的超集或 B 是 A 的子集的键:
c = {k:a[k] for k in a.keys() - b.keys()}
Based on both keys and values @PaulMcG answer
基于键和值@PaulMcG 回答
回答by slavos1
Since I can not (yet) comment: the accepted answerwill fail if there are some keys in B not present in A.
因为我不能(还)评论:如果 B 中的某些键不存在于 A 中,则接受的答案将失败。
Using dict.pop with a default would circumvent it (borrowed from How to remove a key from a Python dictionary?):
使用带有默认值的 dict.pop 会绕过它(借自How to remove a key from a Python dictionary?):
all(A.pop(k, None) for k in B)
or
或者
tuple(A.pop(k, None) for k in B)