测试dict中是否包含dict [英] Test if dict contained in dict

查看:147
本文介绍了测试dict中是否包含dict的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于python dicts,测试平等工作正常:

  first = {one:un,两个:deux,three:trois} 
second = {one:un,two:deux,three:trois}

print(first == second)#结果:True

但是现在我的第二个dict包含我想忽略的一些额外的键:

  first = {one:un,two:deux ,tri:trois} 
second = {one:un,two:deux,three:trois,foo:bar}

有没有一种简单的方法来测试第一个dict是否是第二个dict的一部分,其键和值?



编辑1:



疑似怀疑是如何测试字典的重复包含某些 ,但我有兴趣测试密钥及其值。只包含相同的密钥不会使两个相同。



编辑2:



好的,我现在用四种不同的方法得到一些答案,并证明了他们所有的工作。因为我需要一个快速的过程,我测试了每个执行时间。我创建了三个相同的数字,1000个项目,键和值是长度为10的随机字符串。第二个第三个一些额外的键值对,以及第三个的最后一个非额外键获得一个新值。所以,第一个第二个的子集,但不是第三个。使用模块 timeit 与10000次重复,我得到:

 方法时间[ s] 
first.viewitems()< = second.viewitems()0.9
set(first.items())。issubset(second.items())7.3
len(set first.items())& set(second.items()))== len(first)8.5
all(first [key] == second.get(key,sentinel)for key in first)

我猜到最后一个方法是最慢的方法,但它位于2.
但方法

解决方案

感谢您的答案!您可以使用字典视图

 #Python 2 
如果first.viewitems()< = second.viewitems():
#只有当first是second的子集

#Python 3
if first.items ()< = second.items():
#只有当`first`是'second`的子集

词典视图是 Python 3中的标准在Python 2中,您需要使用视图前缀标准方法。他们的行为就像集合, <= 测试其中一个是否是另一个子集(或等于另一个)。



在Python 3中演示:

 >>> first = {one:un,two:deux,three:trois} 
>>> second = {one:un,two:deux,three:trois,foo:bar}
>>> first.items()< = second.items()
True
>>> first ['four'] ='quatre'
>>>> first.items()< = second.items()
False

这适用于不可哈希的值也是,因为这些键使键值对唯一已经存在。这个文件在这一点上有点令人困惑,但是即使有可变值(例如列表),它也可以起作用:

 >> ;> first_mutable = {'one':['un','een','einz'],'two':['deux','twee','zwei']} 
>>> second'mutable = {'one':['un','een','einz'],'two':['deux','twee','zwei'],'three':['trois' ','drei']}
>>> first_mutable.items()< = second_mutable.items()
True
>>> first_mutable ['one']。append('ichi')
>>> first_mutable.items()< = second_mutable.items()
False

你也可以请使用 all()功能一个生成器表达式使用 object()作为哨兵来简洁地检测到缺失的值:

  sentinel = object()
如果所有(第一个[key] == second.get(key,sentinel)为第一个):
#只有当first是second的子集时,

但是这不像使用字典视图那样可读和表达。


Testing for equality works fine like this for python dicts:

first  = {"one":"un", "two":"deux", "three":"trois"}
second = {"one":"un", "two":"deux", "three":"trois"}

print(first == second) # Result: True

But now my second dict contains some additional keys I want to ignore:

first  = {"one":"un", "two":"deux", "three":"trois"}
second = {"one":"un", "two":"deux", "three":"trois", "foo":"bar"}

Is there a simple way to test if the first dict is part of the second dict, with all its keys and values?

EDIT 1:

This question is suspected to be a duplicate of How to test if a dictionary contains certain keys, but I'm interested in testing keys and their values. Just containing the same keys does not make two dicts equal.

EDIT 2:

OK, I got some answers now using four different methods, and proved all of them working. As I need a fast process, I tested each for execution time. I created three identical dicts with 1000 items, keys and values were random strings of length 10. The second and third got some extra key-value pairs, and the last non-extra key of the third got a new value. So, first is a subset of second, but not of third. Using module timeit with 10000 repetitions, I got:

Method                                                      Time [s]   
first.viewitems() <=second.viewitems()                           0.9 
set(first.items()).issubset(second.items())                      7.3
len(set(first.items()) & set(second.items())) == len(first)      8.5
all(first[key] == second.get(key, sentinel) for key in first)    6.0

I guessed the last method is the slowest, but it's on place 2. But method 1 beats them all.

Thanks for your answers!

解决方案

You can use a dictionary view:

# Python 2
if first.viewitems() <= second.viewitems():
    # true only if `first` is a subset of `second`

# Python 3
if first.items() <= second.items():
    # true only if `first` is a subset of `second`

Dictionary views are the standard in Python 3, in Python 2 you need to prefix the standard methods with view. They act like sets, and <= tests if one of those is a subset of (or is equal to) another.

Demo in Python 3:

>>> first  = {"one":"un", "two":"deux", "three":"trois"}
>>> second = {"one":"un", "two":"deux", "three":"trois", "foo":"bar"}
>>> first.items() <= second.items()
True
>>> first['four'] =  'quatre'
>>> first.items() <= second.items()
False

This works for non-hashable values too, as the keys make the key-value pairs unique already. The documentation is a little confusing on this point, but even with mutable values (say, lists) this works:

>>> first_mutable = {'one': ['un', 'een', 'einz'], 'two': ['deux', 'twee', 'zwei']}
>>> second_mutable = {'one': ['un', 'een', 'einz'], 'two': ['deux', 'twee', 'zwei'], 'three': ['trois', 'drie', 'drei']}
>>> first_mutable.items() <= second_mutable.items()
True
>>> first_mutable['one'].append('ichi')
>>> first_mutable.items() <= second_mutable.items()
False

You could also use the all() function with a generator expression; use object() as a sentinel to detect missing values concisely:

sentinel = object()
if all(first[key] == second.get(key, sentinel) for key in first):
    # true only if `first` is a subset of `second`

but this isn't as readable and expressive as using dictionary views.

这篇关于测试dict中是否包含dict的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆