对于python来说,对等式的测试工作得很好,就像这样:
first = {"one":"un", "two":"deux", "three":"trois"}
second = {"one":"un", "two":"deux", "three":"trois"}
print(first == second) # Result: True但是,现在我的第二个切分包含了一些我想忽略的额外键:
first = {"one":"un", "two":"deux", "three":"trois"}
second = {"one":"un", "two":"deux", "three":"trois", "foo":"bar"}是否有一种简单的方法来测试第一个dict是否是第二个dict的一部分,以及它的所有键和值?
编辑1:
这个问题被怀疑是如何测试字典是否包含的重复,但我对测试键及其值很感兴趣。仅仅包含相同的键并不能使两个切分相等。
编辑2:
好的,我现在用四种不同的方法得到了一些答案,并证明了它们都是有效的。因为我需要一个快速的过程,所以我测试了每个过程的执行时间。我用1000个条目创建了三个相同的切块,键和值是长度为10的随机字符串。second和third得到了一些额外的键值对,而third的最后一个非额外键得到了一个新值。因此,first是second的子集,而不是third的子集。使用模块timeit重复10000次,我得到:
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我猜最后一种方法是最慢的,但它在第2位,但是方法1胜过所有的方法。
谢谢你的回答!
发布于 2015-06-13 12:41:49
您可以使用字典视图
# 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`字典视图是Python 3中的标准,在Python2中,需要用view作为标准方法的前缀。它们的作用类似于集合,如果其中一个子集是(或等于)另一个子集,则进行<=测试。
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', 'drie', 'drei']}
>>> first_mutable.items() <= second_mutable.items()
True
>>> first_mutable['one'].append('ichi')
>>> first_mutable.items() <= second_mutable.items()
False您还可以将函数与生成器表达式一起使用;使用object()作为哨兵,简明地检测缺少的值:
sentinel = object()
if all(first[key] == second.get(key, sentinel) for key in first):
# true only if `first` is a subset of `second`但这并不像使用字典视图那样具有可读性和表现力。
发布于 2015-06-13 12:40:06
all(k in second and second[k] == v for k, v in first.items())如果您知道所有的值都不能是None,那么它将简化为:
all(second.get(k, None) == v for k, v in first.items())发布于 2015-06-13 12:37:24
因此,您基本上想要检查一个字典是否是另一个字典的子集。
first = {"one":"un", "two":"deux", "three":"trois"}
second = {"one":"un", "two":"deux", "three":"trois", "foo":"bar"}
def subset_dic(subset, superset):
return len(set(subset.items()) & set(superset.items())) == len(subset)
print(subset_dic(first, second))指纹:
True如果要抽象出子集/超集部分,请执行以下操作:
def subset_dic(dict1, dict2):
return len(set(dict1.items()) & set(dict2.items())) == len(min((dict1, dict2), key=len))注意事项:如果任何值是可变的对象,这将无法工作。因此,您可以在函数中添加一个附加步骤(将可变对象转换为不可变模拟),以克服这一限制。
https://stackoverflow.com/questions/30818694
复制相似问题