How to elegantly check if a dictionary has a given structure?

dictionary, python

Solution

Firstly, I think the more 'Pythonic' thing might be to ask forgiveness rather than permission - to check when you needed a property whether the data structure had that property.

But on the other hand, that doesn't help if you've been asked to create something to check it's well-formed. :)

So if you need to check, you can use something like the schema library to define what your data structure should look like, and then check other data structures against that schema.

Problem

I have a dictionary with the following structure: ``` D = { 'rows': 11, 'cols': 13, (i, j): { 'meta': 'random string', 'walls': { 'E': True, 'O': False, 'N': True, 'S': True } } } # i ranging in {0 .. D['rows']-1} # j ranging in {0 .. D['cols']-1} ``` I want to write a function that takes an arbitrary object as argument and checks if it has that structure. This is what I wrote: ``` def well_formed(L): if type(L) != dict: return False if 'rows' not in L: return False if 'cols' not in L: return False nr, nc = L['rows'], L['cols'] # I should also check the int-ness of nr and nc ... if len(L) != nr*nc + 2: return False for i in range(nr): for j in range(nc): if not ((i, j) in L and 'meta' in L[i, j] and 'walls' in L[i, j] and type(L[i, j]['meta']) == str and type(L[i, j]['walls']) == dict and 'E' in L[i, j]['walls'] and 'N' in L[i, j]['walls'] and 'O' in L[i, j]['walls'] and 'S' in L[i, j]['walls'] and type(L[i, j]['walls']['E']) == bool and type(L[i, j]['walls']['N']) == bool and type(L[i, j]['walls']['O']) == bool and type(L[i, j]['walls']['S']) == bool): return False return True ``` Although it works, I don't like it at all. Is there a Pythonic way to do it? I'm allowed to use just the standard library.

Original source

Related problems