Note that there are some explanatory texts on larger screens.

plurals
  1. POHow do you iterate over two dictionaries and grab the values at the same path?
    text
    copied!<p>I have two dictionaries, that are of similar structure...meaning they(should) have the same key structure, even within nested keys. Also, these dicts could have almost any type of nested structure...list, dict, etc... I want to be able to traverse these dictionaries, and grab the two values and return them from a function.</p> <p>Simple Example:</p> <pre><code>dict_a = {'a':1, 'b':2, 'c':{'d':3}} dict_b = {'a':2, 'b':4, 'c':{'d':6}} #Note the structure is the same for these dicts #I want to be able to do something like: &gt;&gt;get_values( dict_a, dict_b) [(1,2),(2,4),(3,6)] </code></pre> <p>I came up with a solution to it myself by traversing one dictionary, and appending each key(or index if it encounters a list) into a list...as a sort of key-path:</p> <pre><code>key_map = []#A list of all key-paths for a dictionary generate_key_paths(dict_a, [], key_map) def generate_key_paths(value, key_list,key_map ): new_list = [item for item in key_list] if isinstance( value, dict): #Handle list for key, val in value.iteritems(): new_list.append( key) self._generate_key_paths( val, new_list, key_map ) new_list = [item for item in key_list] elif isinstance( value, list ): #Handle list for idx,item in enumerate(value): new_list.append( idx ) self._generate_key_paths( item, new_list, key_map ) new_list = [item for item in key_list] else: #Handle data--reached farthest point you can go #So just append (key-path, value) to key_map key_map.append((new_list, value ) ) </code></pre> <p>And then once you have a list of key-path,value tuples...take the path, and try to reach it on the second dictionary to get its value...</p> <pre><code>val_list = [] for item in key_map: value = get_value( item[0] ) if value is not None: val_list.append( (item[1], value ) ) def get_value( key_list ): value = dict_b for item in key_list: try: value = value[item] except: value = None break return value </code></pre> <p>This works quite well for all structures a dictionary could have, but it seems like a lot of work. Is there a more pythonic way of achieving this? Is there a faster, more efficient way?</p> <p>EDIT: I'm looking for a value that isn't a list or a dict, so when these values are reached, it should iterate inside them, until it finds a value. It is guaranteed that if it's a list, it will be a list of dicts, so there should always be some sort of key:value relationship to follow.</p> <p>For example a possible dict could look like this: </p> <p><code>dict_a = {'a':1, 'b':2, 'c':[{'d':5},{'e':6}]}</code></p> <p><code>dict_b = {'a':2, 'b':4, 'c':[{'d':10},{'e':12}]}</code></p> <p>Answer: <code>[(1,2), (2,4), (5,10), (6,12)]</code></p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload