例如,dict a
包含dict b1
,因为:
a = { 'name': 'mary', 'age': 56, 'gender': 'female' }
b1 = { 'name': 'mary', 'age': 56 }
但这是False,因为密钥name
的值不同。
b2 = { 'name': 'elizabeth', 'age': 56 }
这个"短路"。当发现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
set(b1.iteritems()) <= set(a.iteritems())
CCD_ 9实现了对CCD_ 10对象的子集关系。当两个dict中的键和值都是可散列的(字符串、元组和int是,列表不是)时,这就起作用了。
我将回答字典是否兼容,因此我更改了示例:
>>> 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)
是两个字典之间所有关键字的交集。CCD_ 12将早于任何相应的值失配。
是有一个内置函数。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
s相同的含义。
在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'
While:
In [11]: a.items() <= a.items() Out[11]: True
它的内存效率更高,因为它不需要任何其他分配。使用
set
可能会使使用的内存增加一倍。- 它更快(因为它避免了新分配的开销)
提出的解决方案的简单基准测试(在Python 2中):
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
CCD_ 24比第二快的解决方案快约2倍。