Home > Back-end >  How iterate over a dictionary of several levels and array of values
How iterate over a dictionary of several levels and array of values

Time:10-19

I have a dictionary made of array of values which I would like to get all the values related to condition. This is a dummy sample of the structure:

d = {'condition': 'Approval expected.', 'sub_conditions': [
    {'condition': 'Approved Activities: {reading} {crafting}', 'sub_conditions': [
        {'condition': 'Field Areas: # of areas, dimensions - {start_date} {end_date} {email}', 'sub_conditions': [
            {'condition': 'Room Areas: # of rooms, dimensions - {start_date} {end_date} {email}',
             'sub_conditions': []}]}]}]}

subconditions is an array of dictionaries made of conditions which I would like to get. Currently, I am visiting each condition value as follows:

for layer_one in d['sub_conditions']:
    print(layer_one['condition'])
    for layer_two in layer_one['sub_conditions']:
        print(layer_two['condition'])
        for layer_three in layer_two['sub_conditions']:
            print(layer_three['condition'])
            #it can have more layers

This is giving me the output I need:

Approved Activities: {reading} {crafting}
Field Areas: # of areas, dimensions - {start_date} {end_date} {email}
Room Areas: # of rooms, dimensions - {start_date} {end_date} {email}

I was wondering better ways to iterate over this type of dictionary. What would be the best approach in this case?

CodePudding user response:

You could use a recursive function for this:

d = {'condition': 'Approval expected.', 'sub_conditions': [
    {'condition': 'Approved Activities: {reading} {crafting}', 'sub_conditions': [
        {'condition': 'Field Areas: # of areas, dimensions - {start_date} {end_date} {email}', 'sub_conditions': [
            {'condition': 'Room Areas: # of rooms, dimensions - {start_date} {end_date} {email}',
             'sub_conditions': []}]}]}]}


def print_conditions(my_dict: dict):
    """Print `condition` within each list of `sub_conditions`"""
    for sub_condition in my_dict['sub_conditions']:
        print(sub_condition['condition'])
        print_conditions(sub_condition)


print_conditions(d)

Output:

Approved Activities: {reading} {crafting}
Field Areas: # of areas, dimensions - {start_date} {end_date} {email}
Room Areas: # of rooms, dimensions - {start_date} {end_date} {email}

CodePudding user response:

Whenever you find yourself in situations where you're unsure of how many levels a nested structure can go, think of recursion.

Taking your code, and modifying it into a recursive function, we call the function on the 'parent' dictionary, and then recurse for every 'inner' dictionary present inside.

def recurse(curr_dict):
    if 'sub_conditions' in curr_dict:
        for inner_dict in curr_dict['sub_conditions']:
            print(inner_dict['condition'])
            recurse(inner_dict)

d = {'condition': 'Approval expected.', 'sub_conditions': [
    {'condition': 'Approved Activities: {reading} {crafting}', 'sub_conditions': [
        {'condition': 'Field Areas: # of areas, dimensions - {start_date} {end_date} {email}', 'sub_conditions': [
            {'condition': 'Room Areas: # of rooms, dimensions - {start_date} {end_date} {email}',
             'sub_conditions': []}]}]}]}
             
recurse(d)

Outputs the same thing that your code does, but now you needn't worry about adding more loops, the recursive code should work regardless of how many layers deep the dictionary gets nested.

Approved Activities: {reading} {crafting}
Field Areas: # of areas, dimensions - {start_date} {end_date} {email}
Room Areas: # of rooms, dimensions - {start_date} {end_date} {email}

CodePudding user response:

dict_of_conditions = d = {'condition': 'Approval expected.', 'sub_conditions': [
    {'condition': 'Approved Activities: {reading} {crafting}', 'sub_conditions': [
        {'condition': 'Field Areas: # of areas, dimensions - {start_date} {end_date} {email}', 'sub_conditions': [
            {'condition': 'Room Areas: # of rooms, dimensions - {start_date} {end_date} {email}',
             'sub_conditions': []}]}]}]}

conditions = []
def get_conditions(condition_dict):
    print(condition_dict["condition"])
    conditions.append(condition_dict["condition"])
    if len(condition_dict["sub_conditions"]) > 0:
        get_conditions(condition_dict["sub_conditions"][0]) # I am selecting the first item in the "sub_conditions" list because there seems to be only always one item in the array

This is called a recursive function. Basically, it takes in a dict, prints the condition and, if the length of the sub_conditions array is greater than 0, it calls itself on it again.

  • Related