我有一些动态生成的词典。它们是使用from collections import defaultdict
生成的,如下所示:
a= defaultdict(list, {'speed_limit': [('0', '70')]})
b= defaultdict(list, {'speed_limit': [('0', '70'),('0', '60'),
('0','50')],'road_obstacles': [('0', '8')]})
我想要什么
如果' a'在' b'在上述情况下也是如此。只要 当内部的键或值不同时打印。
在上述情况中,a
有1个元组,b
有3个元组,但是a
的元组
是b
的一部分,所以不应有任何区别。
我尝试了什么
我尝试了一种非常保守的嵌套循环方法,但是效率不高。另外,当我比较的结构变得复杂时,它无法处理这种情况。
这是我尝试过的,这种方法对于大型结构来说非常低效:
for key,value in a.iteritems():
for key1,value1 in b.iteritems():
if key!=key1:
print "doesn't matches", key,value, key1,value1
if key==key1: #check for values
if value==value1: #if values are same
print "key and value matches", key,value,key1,value1
if value!=value1: #if values not same
print "key matches but value differs", key,value,key1,value1
答案 0 :(得分:1)
目前,您正在迭代两个词典,主要生成笛卡尔积。听起来像你真正想要的就是工会。
联合运算符是|
。它适用于集合。要查找两个词典中所有键的并集,请使用 set(a.keys()) | set(b.keys())
修改: ivan_pozdeev points out可以使用set(a) | set(b)
更快地计算集合。
然后,您可以迭代该集合一次,检查key in a
,key in b
,以及值是否具有必要的公共元素(set(a_value) & set(b_value)
)。这是一个例子:
all_keys = set(a.keys()) | set(b.keys())
for k in all_keys:
if k in a:
if k in b:
print("Key is in both dictionaries:",k)
a_value,b_value = a[k],b[k]
if set(a_value) & set(b_value)):
print("Values match")
else:
print("Values do not match")
else: print("Key is in a but not b:",k)
else: print("Key is in b but not a:",k)
这只是一种方式。另一种方法是计算三组:set(a.keys()) - set(b.keys())
中的密钥a
但b
中的密钥set(b.keys()) - set(a.keys())
,b
中的密钥a
但set(a.keys()) & set(b.keys())
中的密钥不是{{1}} }和{{1}}表示两个词典中的键。
答案 1 :(得分:1)
对于集合操作,最快的方法应该是将dict
转换为set
并使用set
实现中的那些(因为它们在C中实现):
>>> [
set((k,iv) for k,v in var.iteritems() for iv in v)
for var in a,b]
[{('speed_limit', ('0', '70'))},
{('road_obstacles', ('0', '8'))
('speed_limit', ('0', '50')),
('speed_limit', ('0', '60')),
('speed_limit', ('0', '70'))}]
>>> sa,sb=_
>>> sb > sa
True
>>> sb - sa
{('road_obstacles', ('0', '8')),
('speed_limit', ('0', '50')),
('speed_limit', ('0', '60'))}
>>> sa - sb
set()
缺点:循环的第一步,尽管优化友好(也许您最好从一开始就将它们存储为set
?决定取决于您需要执行的频率{ {1}} - 友好与set
- 友好的行动)
对示例中变量的dict
测试显示时间大致相同:
timeit
对包含~1000个元素的随机示例进行def loops(): <your code>
def sets(): <my code up to b-a>
<a and b are being taken from the interactive namespace>
In [85]: timeit sets
The slowest run took 14.36 times longer than the fastest. This could mean that a
n intermediate result is being cached
1000000 loops, best of 3: 253 ns per loop
In [86]: timeit loops
The slowest run took 13.23 times longer than the fastest. This could mean that a
n intermediate result is being cached
1000000 loops, best of 3: 253 ns per loop
测试表明,我的代码似乎开始优于您的代码,但差异很大:
timeit