UPDATE: I updated the code for more convenient viewing of lists. I also commented on the code to make it more understandable if you need to change it.
This answer is not 100% general right now, but it can be easily expanded to fit what you need.
def print_error(exp, act, path=[]): if path != []: print 'MATCH LIST ITEM: %s' % '>>'.join(path) print 'EXPECTED: %s' % str(exp) print 'ACTUAL: %s' % str(act) print '' def copy_append(lst, item): foo = lst[:] foo.append(str(item)) return foo def deep_check(comp, compto, path=[], print_errors=True):
With your voice recorders as input, I get:
MATCH LIST ITEM: Person>>Age EXPECTED: 60 ACTUAL: NOT_FOUND MATCH LIST ITEM: Person>>Movies EXPECTED: {'The Last Day': {'Director': 'Mr. Kapoor', 'Year': 1990}, 'Monster': {'Director': 'Mr. Khanna', 'Year': 1991}} ACTUAL: NOT_FOUND MATCH LIST ITEM: Person>>Children>>Lname EXPECTED: Roshan ACTUAL: Losan MATCH LIST ITEM: Person>>Children>>Children EXPECTED: Kamal ACTUAL: NOT_FOUND MATCH LIST ITEM: Person>>Children>>Children EXPECTED: NOT_FOUND ACTUAL: Ajamal MATCH LIST ITEM: Person>>Children>>Children EXPECTED: Parveen ACTUAL: NOT_FOUND
Comparison of path lists updated to these two lists:
['foo', 'bar'] ['foo', 'bing', 'bar']
The only error that occurs is that "bing" is not on the first list. With string values, the value can either be in a list or not, but the problem arises when you compare a list of dicts. As a result, you will get voice recorders from the list that do not correspond to different degrees, and the knowledge that dictations are compared with them is not direct.
My implementation solves this by assuming that the dicts pairs that create the fewest errors are the ones that need to be compared with each other. For instance:
test1 = { "Name": "Org Name", "Members": [ { "Fname": "foo", "Lname": "bar", "Gender": "Neuter", "Roles": ["President", "Vice President"] }, { "Fname": "bing", "Lname": "bang", "Gender": "Neuter", "Roles": ["President", "Vice President"] } ] } test2 = { "Name": "Org Name", "Members": [ { "Fname": "bing", "Lname": "bang", "Gender": "Male", "Roles": ["President", "Vice President"] }, { "Fname": "foo", "Lname": "bar", "Gender": "Female", "Roles": ["President", "Vice President"] } ] }
Produces this conclusion:
MATCH LIST ITEM: Members>>Gender EXPECTED: Neuter ACTUAL: Female MATCH LIST ITEM: Members>>Gender EXPECTED: Neuter ACTUAL: Male