计算字典值列表之间的差异

时间:2015-07-09 16:19:47

标签: python algorithm dictionary

我有一些动态生成的词典。它们是使用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

2 个答案:

答案 0 :(得分:1)

目前,您正在迭代两个词典,主要生成笛卡尔积。听起来像你真正想要的就是工会。

联合运算符是|。它适用于集合。要查找两个词典中所有键的并集,请使用 set(a.keys()) | set(b.keys())

修改: ivan_pozdeev points out可以使用set(a) | set(b)更快地计算集合。

然后,您可以迭代该集合一次,检查key in akey 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())中的密钥ab中的密钥set(b.keys()) - set(a.keys())b中的密钥aset(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()
  • 优点:所有复杂的操作都在C
  • 缺点:循环的第一步,尽管优化友好(也许您最好从一开始就将它们存储为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