Home > Software engineering >  Convert each list element into a nested dictionary key
Convert each list element into a nested dictionary key

Time:11-23

There is this list of string that I need to use to create a nested dictionary with some values ['C/A', 'C/B/A', 'C/B/B']

The output will be in the format {'C': {'A': [1, 2, 3], 'B': {'A': [1, 2, 3], 'B': [1, 2, 3]}}}

I've tried to use the below code to create the nested dictionary and update the value, but instead I get {'C': {'A': [1, 2, 3], 'C': {'B': {'A': [1, 2, 3], 'C': {'B': {'B': [1, 2, 3]}}}}}} as the output which is not the correct format. I'm still trying to figure out a way. any ideas?

s = ['C/A', 'C/B/A', 'C/B/B']
new = current = dict()
for each in s:
    lst = each.split('/')
    for i in range(len(lst)):
        current[lst[i]] = dict()
        if i != len(lst)-1:
            current = current[lst[i]]
        else:
            current[lst[i]] = [1,2,3]
            
print(new)

CodePudding user response:

You can create a custom Tree class:

class Tree(dict):
    '''
    Create arbitrarily nested dicts.

    >>> t = Tree()
    >>> t[1][2][3] = 4
    >>> t
    {1: {2: {3: 4}}}

    >>> t.set_nested_item('a', 'b', 'c', value=5)
    >>> t
    {1: {2: {3: 4}}, 'a': {'b': {'c': 5}}}
    '''
    
    def __missing__(self, key):
        self[key] = type(self)()
        return self[key]
    
    def set_nested_item(self, *keys, value):
        head, *rest = keys
        if not rest:
            self[head] = value
        else:
            self[head].set_nested_item(*rest, value=value)

>>> s = ['C/A', 'C/B/A', 'C/B/B']
>>> output = Tree()
>>> default = [1, 2, 3]

>>> for item in s:
...     output.set_nested_item(*item.split('/'), value=list(default))

>>> output
{'C': {'A': [1, 2, 3], 'B': {'A': [1, 2, 3], 'B': [1, 2, 3]}}}

CodePudding user response:

You do not need numpy for this problem, but you may want to use recursion. Here is a recursive function add that adds a list of string keys lst and eventually a list of numbers to the dictionary d:

def add(lst, d):
    key = lst[0]
    if len(lst) == 1: # if the list has only 1 element
        d[key] = [1, 2, 3] # That element is the last key
        return
    if key not in d: # Haven't seen that key before
        d[key] = dict()
    add(lst[1:], d[key]) # The recursive part

To use the function, create a new dictionary and apply the function to each splitter string:

d = dict()
for each in s:
    add(each.split("/"), d)
# d
# {'C': {'A': [1, 2, 3], 'B': {'A': [1, 2, 3], 'B': [1, 2, 3]}}}
  • Related