是否有一个内置功能可以说一个dict a包含另一个dict



例如,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倍。

最新更新