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}
我确实想获得:
A-B = {'10':1, '12':1, '10':2, '11':3}
我不想得到:
a) 当基于键时:
{'10':1, '12':1, '10':2}
或
b) 当基于值时:
{'11':3}
result = A.copy()
[result.pop(key) for key in B if B[key] == A[key]]
获取 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()))
另一种使用集合效率的方法。这个 可能 比 的答案更具多用途。他的回答非常好,简洁,所以我点赞了。
diffKeys = set(a.keys()) - set(b.keys())
c = dict()
for key in diffKeys:
c[key] = a.get(key)
编辑:这里有一个假设,基于 OP 的问题,dict B 是 dict A 的子集,B 中的 key/val 对在 A 中。上面的代码将产生意想不到的结果如果您没有严格使用 key/val 子集。感谢史蒂文在他的评论中指出这一点。
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}
仅基于假设 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 回答
因为我(还)不能发表评论:如果 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)
要减去字典,您可以这样做:
A.subtract(乙)
注意:在 B 有 A 没有的键的情况下,这会给你负值。
Keys views are set-like since their entries are unique and hashable. If all values are hashable, so that (key, value) pairs are unique and hashable, then the items view is also set-like. (Values views are not treated as set-like since the entries are generally not unique.) For set-like views, all of the operations defined for the abstract base class collections.abc.Set are available (for example, ==, <, or ^).
所以你可以:
>>> 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
.
P.S. 字典中不能有重复键。
>>> 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}
我有 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}
我确实想获得: A-B = {'10':1, '12':1, '10':2, '11':3}
我不想得到:
a) 当基于键时:
{'10':1, '12':1, '10':2}
或
b) 当基于值时:
{'11':3}
result = A.copy()
[result.pop(key) for key in B if B[key] == A[key]]
获取 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()))
另一种使用集合效率的方法。这个 可能 比
diffKeys = set(a.keys()) - set(b.keys())
c = dict()
for key in diffKeys:
c[key] = a.get(key)
编辑:这里有一个假设,基于 OP 的问题,dict B 是 dict A 的子集,B 中的 key/val 对在 A 中。上面的代码将产生意想不到的结果如果您没有严格使用 key/val 子集。感谢史蒂文在他的评论中指出这一点。
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}
仅基于假设 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 回答
因为我(还)不能发表评论:如果 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)
要减去字典,您可以这样做:
A.subtract(乙)
注意:在 B 有 A 没有的键的情况下,这会给你负值。
Keys views are set-like since their entries are unique and hashable. If all values are hashable, so that (key, value) pairs are unique and hashable, then the items view is also set-like. (Values views are not treated as set-like since the entries are generally not unique.) For set-like views, all of the operations defined for the abstract base class collections.abc.Set are available (for example, ==, <, or ^).
所以你可以:
>>> 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
.
P.S. 字典中不能有重复键。
>>> 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}