Home > Back-end >  Generating a nested dictionary from a list of lists
Generating a nested dictionary from a list of lists

Time:09-19

I am new to python and I'm trying to filter my data based on a list of lists with some common values. My input is a list of list. I tried using numpy array with unique rows but I guess the logic would be the same.

A = [['apple', 'green', 'sweet', 1.5], 
     ['apple', 'green', 'sweet', 1.0],
     ['apple', 'red', 'sweet', 2.0],
     ['orange', 'orange', 'sour', 1.0],
     ['orange', 'orange', 'sweet', 1.2],
     ['apple', 'yellow', 'sour', 0.5],
     ['banana', 'yellow', 'sweet', 1.0]]

I want an output that is something like:

A_dict = {'apple':{'green': {'sweet':[1.5, 1.0]}, 
                   'yellow': {'sour':0.5},
                   'red':{'sweet':2.0}},
          'orange': {'orange':{'sour': 1.0,
                               'sweet': 1.2}},
          'banana':{'yellow': {'sweet': 1.0}}} 

My goal is to get a dictionary that keeps on updating the next option based on the previous choice of inputs for a dash app. I tried using collections.defaultdict but I could only do the first two columns.

keys =A[:,0]
values = A[:,1:]
from collections import defaultdict
A_dict =defaultdict(list)
for ii, jj in zip(keys,values[:,0]):
    A_dict[ii].append(jj)

Edit: I tried the defaultdict method but I could not figure out a way to use all the columns. I have a data that has more columns and rows, so wanted to automate the task.

Thanks

CodePudding user response:

Rather than having the value be a Union[int, List[int]], the solution becomes a lot easier if its just a List[int].

Using this format we can easily use a defaultdict to create the data-structure. The argument to the default dict is a function that creates a new value when a key is requested that is not yet assigned. So we can use a lambda to compose inner defaultdicts:

from collections import defaultdict
import json

A = [['apple', 'green', 'sweet', 1.5],
     ['apple', 'green', 'sweet', 1.0],
     ['apple', 'red', 'sweet', 2.0],
     ['orange', 'orange', 'sour', 1.0],
     ['orange', 'orange', 'sweet', 1.2],
     ['apple', 'yellow', 'sour', 0.5],
     ['banana', 'yellow', 'sweet', 1.0]]

a_dict = defaultdict(lambda: defaultdict(lambda: defaultdict(list)))

for fruit, color, taste, val in A:
    a_dict[fruit][color][taste].append(val)


print(json.dumps(a_dict, indent=2))
{
  "apple": {
    "green": {
      "sweet": [
        1.5,
        1.0
      ]
    },
    "red": {
      "sweet": [
        2.0
      ]
    },
    "yellow": {
      "sour": [
        0.5
      ]
    }
  },
  "orange": {
    "orange": {
      "sour": [
        1.0
      ],
      "sweet": [
        1.2
      ]
    }
  },
  "banana": {
    "yellow": {
      "sweet": [
        1.0
      ]
    }
  }
}
  • Related