2014-02-05 3 views
0

У меня есть программа, которая сравнивает два питона dicts, и она отлично работает для не вложенных словарей с глубиной 1. Алгоритма довольно прост:Python вложенного ДИКТ сравнить алгоритм

for key in dict1, if not in dict2 
    print "-" key 
for key in dict2, if not in dict1 
    print "+" key 
for dict2Value, if not equal to dict1Value 
    print "+" dict2value 
    print "-" dict1value 

Как я это сказал отлично работает с dicts, которые имеют глубину 1 и не вложены. Как изменить алгоритм работы с вложенными и dicts с большей глубиной, я застрял на некоторое время.

мой код:

def print_diff(dict1, dict2): 
    for n in dict1: 
     if n not in dict2: 
      print('- "' + str(n) + '":') 
    for n in dict2: 
     if n not in dict1: 
      print('+ "' + str(n) + '":') 
      continue 
     if dict2[n] != dict1[n]: 
      if type(dict2[n]) not in (dict, list): 
       print('- "' + str(n) + '" : "' + str(dict1[n])) 
       print('+ "' + str(n) + '" : "' + str(dict2[n])) 
      else: 
       if type(dict2[n]) == dict: 
        print_diff(dict1[n], dict2[n]) 
        continue 
    return 
+0

Какой код вы пробовали ? – Totem

+0

Каков ожидаемый результат для 'dict1 = {'a': 3, 'b': {'b': 4, 'a': 5}}' и 'dict2 = {'a': {'a': 3, 'b': 4}, 'a': 5} '? – Hyperboreus

+0

@Totem добавил мой код к основному сообщению – user3230554

ответ

2

Следующая принимает более короткую форму вывода различий (которые вы можете изменить, чтобы следовать своему усмотрению).

Иерархия обозначается START/STOP на выходе.

>>> def dictdiff(d1, d2): 
    s1, s2 = set(d1), set(d2) 
    in1, in12, in2 = s1 - s2, s1 & s2, s2 - s1 
    if in1: print('Keys only in 1:', sorted(in1)) 
    if in2: print('Keys only in 2:', sorted(in2)) 
    sameval = {key for key in in12 if d1[key] == d2[key]} 
    if sameval: print('Keys with equal values:', sorted(sameval)) 
    diffval = in12 - sameval 
    diffdict = {key for key in diffval if type(d1[key]) == type(d2[key]) == dict} 
    diffother = diffval - diffdict 
    if diffother: print('Keys with different values (that are not both dicts):', sorted(diffother)) 
    for key in sorted(diffdict): 
     print('## START dictdiff for common key', key) 
     dictdiff(d1[key], d2[key]) 
     print('## STOP dictdiff for common key', key) 


>>> d1 = dict(a=1, b=2, c=dict(x=1, y=2), d=1, f=dict(s=1, t=3)) 
>>> d2 = dict(a=1, b=3, c=dict(x=1, y=2), e=1, f=dict(s=1, t=2)) 
>>> dictdiff(d1, d2) 
Keys only in 1: ['d'] 
Keys only in 2: ['e'] 
Keys with equal values: ['a', 'c'] 
Keys with different values (that are not both dicts): ['b'] 
## START dictdiff for common key f 
Keys with equal values: ['s'] 
Keys with different values (that are not both dicts): ['t'] 
## STOP dictdiff for common key f 
>>> 

Это может быть хорошо, чтобы помнить следующее тоже:

>>> d1['c'] is d2['c'] 
False 
>>> d1['c'] == d2['c'] 
True 
>>> 
0

сравнения 2 словаря с использованием рекурсии:

d1= {'a':{'b':{'cs':10},'d':{'cs':20}}} 
d2= {'a':{'b':{'cs':30} ,'d':{'cs':20}},'newa':{'q':{'cs':50}}} 

def findDiff(d1, d2, path=""): 
    for k in d1.keys(): 
     if not d2.has_key(k): 
      print path, ":" 
      print "keys not in d2: " + k, "\n" 
     else: 
      if type(d1[k]) is dict: 
       if path == "": 
        path = k 
       else: 
        path = path + "->" + k 
       findDiff(d1[k],d2[k], path) 
      else: 
       if d1[k] != d2[k]: 
        print path, ":" 
        print " - ", k," : ", d1[k] 
        print " + ", k," : ", d2[k] 

print "comparing d1 to d2:" 
print findDiff(d1,d2) 
print "comparing d2 to d1:" 
print findDiff(d2,d1) 

Выход:

comparing d1 to d2: 
a->b : 
- cs : 10 
+ cs : 30 
None 
comparing d2 to d1: 
a->b : 
- cs : 30 
+ cs : 10 
a : 
keys not in d2: newa 

None 
+0

Пронумерованный для копирования вставки без предоставления кредитов – MohitC

Смежные вопросы