e.g。 dict a
包含dict b1
,因为:
a = { 'name': 'mary', 'age': 56, 'gender': 'female' }
b1 = { 'name': 'mary', 'age': 56 }
但这是假的,因为键name
的值不同。
b2 = { 'name': 'elizabeth', 'age': 56 }
答案 0 :(得分:7)
set(b1.iteritems()) <= set(a.iteritems())
<=
在set
objects上实现子集关系。当两个dicts中的键和值都可以清除时(字符串,元组和整数都是,列表不是),这都可以工作。
答案 1 :(得分:7)
这是“短路”。当找到b2
中不在a
中的all()
的第一项时,>>> a = { 'name': 'mary', 'age': 56, 'gender': 'female' }
>>> b1 = { 'name': 'mary', 'age': 56 }
>>>
>>> all(a[k]==v for k,v in b1.iteritems())
True
>>> b2 = { 'name': 'elizabeth', 'age': 56 }
>>> all(a[k]==v for k,v in b2.iteritems())
False
会立即终止。还避免了创建临时集的内存开销
b
如果a
包含不在>>> all(a.get(k, object())==v for k,v in b2.iteritems())
False
中的密钥,则可以使用此
{{1}}
答案 2 :(得分:2)
如果词典兼容我会回答,所以我改变了样本:
>>> test_compat = lambda d1, d2: all(d1[k]==d2[k] for k in set(d1) & set(d2))
>>> a = { 'name': 'mary', 'age': 56, 'gender': 'female' }
>>> b1 = { 'name': 'mary', 'age': 56, 'phone' : '555' }
>>> b2 = { 'name': 'elizabeth', 'age': 56 }
>>> test_compat(a, b1)
True
>>> test_compat(a, b2)
False
>>> test_compat(b1, a)
True
set(d1) & set(d2)
是两个词典之间所有键的交集。 all
会提前退出任何相应的值不匹配。
答案 3 :(得分:0)
是有内置功能。 dict.items()
返回字典视图,其行为与set
:
In [1]: a = { 'name': 'mary', 'age': 56, 'gender': 'female' }
...: b1 = { 'name': 'mary', 'age': 56 }
...:
In [2]: b1.items() <= a.items()
Out[2]: True
In [3]: b2 = { 'name': 'elizabeth', 'age': 56 }
In [4]: b2.items() <= a.items()
Out[4]: False
运营商<
,<=
>=
和>
与set
的含义相同。
在python2.7中,您可以使用viewitems()
方法访问dict
的视图。
这比明确将项目转换为set
(如其他建议的答案中)要好得多,因为:
它适用于不可用的值:
In [10]: a = {'a': [1]}
...: set(a.items()) <= set(a.items())
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-10-893acb4047c9> in <module>()
1 a = {'a': [1]}
----> 2 set(a.items()) <= set(a.items())
TypeError: unhashable type: 'list'
虽然:
In [11]: a.items() <= a.items()
Out[11]: True
它更节省内存,因为它不需要任何其他分配。使用set
可能加倍使用的内存。
使用建议的解决方案(在python2中)的简单基准:
In [1]: a = {'a'+str(i): i for i in range(500000)}
...: b = a.copy()
...:
In [2]: %timeit set(a.iteritems()) <= set(b.iteritems())
1 loops, best of 3: 810 ms per loop
In [3]: %timeit all(a[k]==v for k,v in b.iteritems())
10 loops, best of 3: 157 ms per loop
In [4]: %timeit all(a.get(k,object())==v for k,v in b.iteritems())
1 loops, best of 3: 237 ms per loop
In [5]: %timeit a.viewitems() <= b.viewitems()
10 loops, best of 3: 80.8 ms per loop
In [6]: def test_compat(d1, d2):
...: return all(d1[k]==d2[k] for k in set(d1) & set(d2))
...:
...: def test_compat2(d1, d2):
...: return all(d1[k] == d2[k] for k in d1.viewkeys() & d2.viewkeys())
...:
In [7]: %timeit test_compat(a, b)
1 loops, best of 3: 514 ms per loop
In [8]: %timeit test_compat2(a, b)
1 loops, best of 3: 500 ms per loop
viewitems()
比第二快的解决方案快2倍。