1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 | class Diff(object):
def __init__(self, first, second, with_values=False, vice_versa=False):
self.difference = []
self.check(first, second, with_values=with_values)
if vice_versa:
self.check(second, first, with_values=with_values)
def check(self, first, second, path='', with_values=False):
if second != None:
if not isinstance(first, type(second)):
message = '%s- %s, %s' % (path, type(first), type(second))
self.save_diff(message, TYPE)
if isinstance(first, dict):
for key in first:
# the first part of path must not have trailing dot.
if len(path) == 0:
new_path = key
else:
new_path = "%s.%s" % (path, key)
if isinstance(second, dict):
if second.has_key(key):
sec = second[key]
else:
# there are key in the first, that is not presented in the second
self.save_diff(new_path, PATH)
# prevent further values checking.
sec = None
# recursive call
self.check(first[key], sec, path=new_path, with_values=with_values)
else:
# second is not dict. every key from first goes to the difference
self.save_diff(new_path, PATH)
self.check(first[key], second, path=new_path, with_values=with_values)
# if object is list, loop over it and check.
elif isinstance(first, list):
for (index, item) in enumerate(first):
new_path = "%s[%s]" % (path, index)
# try to get the same index from second
sec = None
if second != None:
try:
sec = second[index]
except (IndexError, KeyError):
# goes to difference
self.save_diff('%s - %s, %s' % (new_path, type(first), type(second)), TYPE)
# recursive call
self.check(first[index], sec, path=new_path, with_values=with_values)
# not list, not dict. check for equality (only if with_values is True) and return.
else:
if with_values and second != None:
if first != second:
self.save_diff('%s - %s | %s' % (path, first, second), VALUE)
return
def save_diff(self, diff_message, type_):
message = '%s: %s' % (type_, diff_message)
if diff_message not in self.difference:
self.difference.append(message)
|
Comments
For dicts, you might try to use
set(dict1.iteritems()) - set(dict2.iteritems())which will compute the difference for you. fast and efficient. For lists, you might useset(enumerate(list1)) - set(enumerate(list2)). Now generalize the mapper and useset(mapper(json1)) - set(mapper(json2)). No need for 66 lines, which are completely unrelated to Django.#
I think it's good, but not for all cases.
`fir = {"f": "foo"}
sec = {"f": "bar"}`
Your method gives us '[('f', 'foo')]' difference, but the both has the same keys.
`fir = {"f": "foo"}
sec = {"f": [1]}`
Your method does not give you proper difference.
`fir = {"f": {"f": "fir"}}
sec = {"f": {"b": "bar"}}`
#