Home > Blockchain >  How to create a dictionary based on order from list of list in Python
How to create a dictionary based on order from list of list in Python

Time:09-18

My source list looks like this :

source = 
[['Ans1','Section1','Type2'],['Ans2','Section1','Type2'],['Ans3','Section2','Type2'],['Ans4','Section1','Type1']]

I would need to create my target in the following format:

{
   "Type2":{
      "0":{
         "Ans":"Ans1",
         "Section":"Section1"
      },
      "1":{
         "Ans":"Ans2",
         "Section":"Section1"
      },
      "2":{
         "Ans":"Ans3",
         "Section":"Section2"
      }},
   "Type1":{
      "0":{
         "Ans":"Ans4",
         "Section":"Section1"
      }
   },
   "Type3":{
      
   },
   "Type4":{
      
   },
   "Type5":{
      
   }
}

So, last value from the dictionary will become the keys and the order is maintained. Say, for Type2 I have three answers. Hence my target has key as Type2 and it has three inner dictionaries with 0,1,2.

I have already created my empty target dictionary (Type3, Type4, Type5 are empty are there no records for these types in my source) :

empty_target = 
{
   "Type1":{
      "0":{
         "Ans":"",
         "Section":""
      },
      "1":{
         "Ans":"",
         "Section":""
      },
      "2":{
         "Ans":"",
         "Section":""
      }},
   "Type2":{
      "0":{
         "Ans":"",
         "Section":""
      }
   },
   "Type3":{
      
   },
   "Type4":{
      
   },
   "Type5":{
      
   }
}

Can anyone assist me how can I populate empty_target with source? Thanks.

Edit: Added the code to create the empty target:

#Sorting my source data
import operator
source = [['Ans1','Section1','Type2'],['Ans2','Section1','Type2'],['Ans3','Section2','Type2'],['Ans4','Section1','Type1']]
new_ = sorted(source, key = operator.itemgetter(0,2))
print(new_)
[['Ans1', 'Section1', 'Type2'], ['Ans2', 'Section1', 'Type2'], ['Ans3', 'Section2', 'Type2'], ['Ans4', 'Section1', 'Type1']]

#Getting the count of Types
doctype_list = [d[2] for d in new]
docs_count_dict = {}
for x in set(doctype_list):
    docs_count_dict[x] = doctype_list.count(x)
print(docs_count_dict)
{'Type2': 3, 'Type1': 1}

#Sorting the type based on new_ list
sorted_docs = sorted(set(doctype_list),key=doctype_list.index)
sorted_docs_orig = sorted_docs.copy()
print (sorted_docs_orig)
['Type2', 'Type1']

tot_types = ['Type1','Type2','Type3','Type4','Type5']

#Sorting the types out of total types : Note Type2 is ordered first as it is the first type in new_
for val in tot_types:
    if val in sorted_docs:
        continue
    sorted_docs.append(val)
print(sorted_docs)
['Type2', 'Type1', 'Type3', 'Type4', 'Type5']

#Creating my empty target:
api_res = {}
for val in sorted_docs:
    api_res[val] = {}
print (api_res)
{'Type2': {}, 'Type1': {}, 'Type3': {}, 'Type4': {}, 'Type5': {}}

cols = ['Ans','Section']
for key,val in api_res.items():
    if key in docs_count_dict:
        for i in range(docs_count_dict[key]):
            val[i] = dict.fromkeys(cols, "")
print (api_res)
{'Type2': {0: {'Ans': '', 'Section': ''},
  1: {'Ans': '', 'Section': ''},
  2: {'Ans': '', 'Section': ''}},
 'Type1': {0: {'Ans': '', 'Section': ''}},
 'Type3': {},
 'Type4': {},
 'Type5': {}}

CodePudding user response:

It could be simpler first create dictionary with lists

# --- create empty lists ---

tot_types = ['Type1','Type2','Type3','Type4','Type5']

result = {t:[] for t in tot_types}


# it givies: {'Type1': [], 'Type2': [], 'Type3': [], 'Type4': [], 'Type5': []}

# --- fill lists ---

data = [['Ans1','Section1','Type2'],['Ans2','Section1','Type2'],['Ans3','Section2','Type2'],['Ans4','Section1','Type1']]

for a, s, t in data:
    result[t].append({'Ans': a, 'Section': s})
    
print(result)

Result:

{
  'Type2': 
    [{'Ans': 'Ans1', 'Section': 'Section1'}, {'Ans': 'Ans2', 'Section': 'Section1'}, {'Ans': 'Ans3', 'Section': 'Section2'}], 
  'Type1': 
    [{'Ans': 'Ans4', 'Section': 'Section1'}]},
  'Type3': 
    [], 
  'Type4': 
    [], 
  'Type5': 
    []
}

And later convert every list to dictionary

for key, value in result.items():
    dictionary = {str(number): content for number, content in enumerate(value)}
    result[key] = dictionary

print(result)

Result

{ 
  'Type2': 
    {'0': {'Ans': 'Ans1', 'Section': 'Section1'}, '1': {'Ans': 'Ans2', 'Section': 'Section1'}, '2': {'Ans': 'Ans3', 'Section': 'Section2'}}, 
  'Type1': 
    {'0': {'Ans': 'Ans4', 'Section': 'Section1'}}
  'Type3': 
    {}, 
  'Type4': 
    {}, 
  'Type5': 
    {}
}

Full example code:

# --- create empty lists ---

tot_types = ['Type1','Type2','Type3','Type4','Type5']

result = {t:[] for t in tot_types}

print(result)
# it givies: {'Type1': [], 'Type2': [], 'Type3': [], 'Type4': [], 'Type5': []}

# --- fill lists ---

data = [['Ans1','Section1','Type2'],['Ans2','Section1','Type2'],['Ans3','Section2','Type2'],['Ans4','Section1','Type1']]

for a, s, t in data:
    result[t].append({'Ans': a, 'Section': s})
    
print(result)

# --- convert lists to dictionares ---

for key, value in result.items():
    dictionary = {str(number): content for number, content in enumerate(value)}
    result[key] = dictionary

print(result)

CodePudding user response:

I tried this and it gave the same result as yours:

source = 
[['Ans1','Section1','Type2'],['Ans2','Section1','Type2'], 
['Ans3','Section2','Type2'],['Ans4','Section1','Type1']]

# empty_target == d
# start index == si
# source == s

d = {}
si = 0
for i in s:
    if i[-1] not in d:
        si = 0
        d[i[-1]] = {}
        d[i[-1]][str(si)] = {
            "Ans": i[0],
            "Section": i[1]
        }
    else:
        # Get the last key for the current 'Type'
        k = list(d.get(i[-1]).keys())[-1]
        d[i[-1]][str(int(k)   1)] = {
            "Ans": i[0],
            "Section": i[1]
        }

Result:

{
 'Type2': {
    '0': {
        'Ans': 'Ans1',
        'Section': 'Section1'},
    '1': {
        'Ans': 'Ans2',
        'Section': 'Section1'},
    '2': {
        'Ans': 'Ans3',
        'Section': 'Section2'
    }},
 'Type1': {
    '0': {
        'Ans': 'Ans4',
        'Section': 'Section1'
    }
  }
}
  • Related