Home > Blockchain >  Given the list, how to generate a nested dictionary
Given the list, how to generate a nested dictionary

Time:01-07

Given the list below, using Python 3 how can I generate a nested dictionary with list[0] having list[1:] as nested children.

list = [
    ["Layer 1.A", "Layer 1.B"],
    ["layer 2.A", "Layer 2.B"],
    ["Layer 3"],
    ["Layer 4"]
    
]

I have already tried a multitude of things, but none have given me the correct output. I have tried the following already:

  1. tried using python's product (generated all permutations, but did not give correct output. It look like:
[
    ["Layer 1.A", "Layer 2.A", "Layer 3", "Layer 4"],
    ["Layer 1.A", "Layer 2.B", "Layer 3", "Layer 4"],
    ["Layer 1.B", "Layer 2.A", "Layer 3", "Layer 4"],
    ["Layer 1.B", "Layer 2.B", "Layer 3", "Layer 4"]
]
  1. tried creating a nested dictionary using nested for loops (couldn't figure out how to append to dictionary)
  2. Tried using recursion (trying dict(zip(keys, dictionary) for keys in product(*dictionary2)), dict or zip iterated trough each element of each string)
  3. tried using a lambda function

Output desired: Please note how only the first layer changes, and the guts are the same.

[
    {"Layer 1.A":
        {
            "Layer 2.A": 
            {
                "Layer 3" : "Layer 4"
            },
            "Layer 2.B":
            {
                "Layer 3" : "Layer 4"
            }
        }
    },
    {"Layer 1.B":
        {
            "Layer 2.A": 
            {
                "Layer 3" : "Layer 4"
            },
            "Layer 2.B":
            {
                "Layer 3" : "Layer 4"
            }
        }
    }
]

CodePudding user response:

You generated all the permutations. Now create your nested dictionary from those permutations. To do this, we can define a function that will take the original dictionary, a list of keys, and the value to set at that nested key. If a key doesn't exist, it is created and its value is set to a new dictionary

def nested_set(obj, keys, value):
    for key in keys[:-1]:
        try:
            # Drill down until the penultimate key
            obj = obj[key]
        except KeyError:
            obj[key] = {}
            obj = obj[key]
    # Set value of last key
    obj[keys[-1]] = value

For example, doing nested_set(my_dict, ['a', 'b', 'c'], 'd') on an empty my_dict = dict() gives the result:

{'a': {'b': {'c': 'd'}}}

Knowing this, you can use your list of permutations like so:

perms = [
    ["Layer 1.A", "Layer 2.A", "Layer 3", "Layer 4"],
    ["Layer 1.A", "Layer 2.B", "Layer 3", "Layer 4"],
    ["Layer 1.B", "Layer 2.A", "Layer 3", "Layer 4"],
    ["Layer 1.B", "Layer 2.B", "Layer 3", "Layer 4"]
]

my_dict = dict()
for p in perms:
    nested_set(my_dict, p[:-1], p[-1])

which gives almost the result you want:

{
    'Layer 1.A': {
        'Layer 2.A': {
            'Layer 3': 'Layer 4'
        },
        'Layer 2.B': {
            'Layer 3': 'Layer 4'
        }
    },
    'Layer 1.B': {
        'Layer 2.A': {
            'Layer 3': 'Layer 4'
        },
        'Layer 2.B': {
            'Layer 3': 'Layer 4'
        }
    }
}

Converting this to the desired list is easy:

result = [{k: v} for k, v in my_dict.items()]

which gives:

[
    {
        'Layer 1.A': {
            'Layer 2.A': {
                'Layer 3': 'Layer 4'
            },
            'Layer 2.B': {
                'Layer 3': 'Layer 4'
            }
        }
    },
    {
        'Layer 1.B': {
            'Layer 2.A': {
                'Layer 3': 'Layer 4'
            },
            'Layer 2.B': {
                'Layer 3': 'Layer 4'
            }
        }
    }
]

CodePudding user response:

This feels like a natural problem for a recursive solution.

def Cartesian(theList):
    if len(theList) == 2:
        result = [ [x,y] for x in theList[0] for y in theList[1] ]
        return result 
    else:
        result = [[x,y] for x in theList[0] for y in Cartesian(theList[1:])]
        return result 

This implementation will return a list with the nested structure that you are seeking. I don't really know much about formatting the result as JSON.

  • Related