so i came up with a diff method to compare 2 dicts. i found it pretty useful so i thought i'd share it with everyone. you can see the doctest to check out suggested uses. since we can't modify built-ins, i demonstrated adding a diff method to OrderedDict to show how one could add it to your own mapping objects.
the core logic is compatible with python2 and 3 (i've only tested using 2.6.5 and 3.1.2). the doctest is suited for python3 though. the interface is pretty straightforward. it would be awesome to have this sucker as a method on the builtin dict, but that'd take a pep, no? -- Jin Yi
__author__ = 'razamatan_retral_net_ignore_com' from collections import Mapping def diffdict(left, right): ''' returns the deep diff of two dicts. the return value the tuple (left_diff, right_diff) >>> diffdict(1, None) (1, None) >>> diffdict({1:2}, None) ({1: 2}, None) >>> diffdict({1:2}, {3:4}) ({1: 2, 3: <class 'KeyError'>}, {1: <class 'KeyError'>, 3: 4}) >>> from collections import OrderedDict >>> x = OrderedDict({1:2, 3:{4:{5:[6,7], 8:9}}}) >>> diffdict(x, x) (None, None) >>> y = {1:2, 3:[4]} >>> diffdict(x, y) ({3: {4: {8: 9, 5: [6, 7]}}}, {3: [4]}) >>> y = {1:2, 3:{4:{5:[6,7]}}} >>> diffdict(x, y) ({3: {4: {8: 9}}}, {3: {4: {8: <class 'KeyError'>}}}) >>> y = {1:2, 3:{4:{5:{6:7}, 8:9}}} >>> diffdict(x, y) ({3: {4: {5: [6, 7]}}}, {3: {4: {5: {6: 7}}}}) >>> del y[3] >>> diffdict(x, y) ({3: {4: {8: 9, 5: [6, 7]}}}, {3: <class 'KeyError'>}) >>> y = {1:2, 3:{4:{5:[6,10], 8:9}}} >>> diffdict(x, y) ({3: {4: {5: [6, 7]}}}, {3: {4: {5: [6, 10]}}}) >>> y = {1:100, 3:{4:{5:[6,7], 8:9}}} >>> diffdict(x, y) ({1: 2}, {1: 100}) >>> diffdict(y, x) ({1: 100}, {1: 2}) >>> x.__class__.diff = diffdict >>> x.__class__.__xor__ = diffdict >>> x.diff(x) (None, None) >>> x ^ y ({1: 2}, {1: 100}) ''' # base case if not isinstance(left, Mapping) or not isinstance(right, Mapping): return (left, right) # key exclusivity left_diff = dict(i for i in left.items() if i[0] not in right) right_diff = dict(i for i in right.items() if i[0] not in left) right_diff.update((k, KeyError) for k in left_diff if k not in right_diff) left_diff.update((k, KeyError) for k in right_diff if k not in left_diff) # value differences for k in (k for k in left if k in right): if left[k] != right[k]: (ld, rd) = diffdict(left[k], right[k]) left_diff[k] = ld or None right_diff[k] = rd or None left_diff = left_diff or None right_diff = right_diff or None return (left_diff, right_diff)
-- http://mail.python.org/mailman/listinfo/python-list