Home > database >  Filling up values of a dict, which in itself is in a list
Filling up values of a dict, which in itself is in a list

Time:05-19

I have a problem. I have a list and this in turn contains dicts. The problem is that the dicts can have different sizes. That some elements are missing in some dicts. Is there an option to fill the dicts with the missing attributes? It is only a matter of filling up the keys and the values can simply be filled up with None.

The following example

[
{'_id': 'orders/213123',
 'contactEditor': {'name': 'Max Power',
                   'phone': '1234567'},
 'isCompleteDelivery': False,
},
{'_id': 'orders/2173823',
 'contactEditor': {'name': 'Michael'},
},
]

It turns out that the first element has the most keys and the second element is missing the following keys phone and isCompleteDelivery.

this is filled in and it looks like this

[
{'_id': 'orders/213123',
 'contactEditor': {'name': 'Max Power',
                   'phone': '1234567'},
 'isCompleteDelivery': False,
},
{'_id': 'orders/2173823',
 'contactEditor': {'name': 'Michael',
                   'phone': None},
 'isCompleteDelivery': None,
},
]

This gives me which dict has the most elements and the number.

%%time
highest_element = 0
elements = 0
for i, element in enumerate(myList):
    counted = count(myList[i])
    if(counted > elements):
        elements = counted
        highest_element = i
        
print(str(elements)   " "   str(highest_element))
myList = [
{'_id': 'orders/213123',
 'contactEditor': {'name': 'Max Power',
  'phone': '1234567',
  'email': '[email protected]'},
 'contactSoldToParty': {'name': 'Max Not',
  'phone': '123456789',
  'email': '[email protected]'},
 'isCompleteDelivery': False,
 'metaData': {'dataOriginSystem': 'Goods',
  'dataOriginWasCreatedTime': '10:12:12',},
 'orderDate': '2021-02-22',
 'orderDateBuyer': '2021-02-22',
},
{'_id': 'orders/12323',
 'contactEditor': {'name': 'Max Power2',
  'phone': '1234567',
  'email': '[email protected]'},
 'contactSoldToParty': {'name': 'Max Not',
  'phone': '123456789',
  'email': '[email protected]'},
 'isCompleteDelivery': False,
 'metaData': {'dataOriginSystem': 'Goods',
  'dataOriginWasCreatedTime': '10:12:12',},
 },
{'_id': 'orders/12323',
 'contactEditor': {'name': 'Max Power2',
  'phone': '1234567',
  'email': '[email protected]'},
 'contactSoldToParty': {'name': 'Max Not',
  'phone': '123456789',
  'email': '[email protected]'},
 'orderDate': '2021-02-22',
 'orderDateBuyer': '2021-02-22',
 },
{'_id': 'orders/12323',
 'contactEditor': {'name': 'Max Power2',
  'phone': '1234567',
  'email': '[email protected]'},
 'contactSoldToParty': {'name': 'Max Not',},
 'isCompleteDelivery': False,
 },
]

CodePudding user response:

This code make a key if not present in dictionary with the value None.

lst = [
{'_id': 'orders/213123',
 'contactEditor': {'name': 'Max Power',
                   'phone': '1234567'},
 'isCompleteDelivery': False,
},
{'_id': 'orders/2173823',
 'contactEditor': {'name': 'Michael'},
},
]

complete_dict = {'_id': None,
 'contactEditor': {'name': None,
                   'phone': None},
 'isCompleteDelivery': None,
} 

# here complete dictionary means which is contain all possible keys.
all_keys = complete_dict.keys() 
for i,value in enumerate(lst):
    for a in all_keys:
        try:
            value[a]
        except KeyError:
            value[a]=None
        else:
            v = value[a]
            if isinstance(v,dict):
                for a2 in complete_dict[a].keys():
                    try:
                        v[a2]
                    except KeyError:
                        v[a2]=None
                value[a]=v

    del lst[i]
    lst.insert(i,value)
print(lst)

OUTPUT

[{'_id': 'orders/213123',
 'contactEditor': {'name': 'Max Power', 'phone': '1234567'},
 'isCompleteDelivery': False},
 {'_id': 'orders/2173823',
 'contactEditor': {'name': 'Michael', 'phone': None}, 
 'isCompleteDelivery': None}]

CodePudding user response:

If I understand the problem correctly, it seems that you need to construct a superset of all possible keys. Once you have that you can iterate over the list and set default values in each dictionary. Now that the "top level" dictionaries have been adjusted you need to step down a level and do the same thing for the nested dictionaries. This code is limited to the data structure as shown in the question.

list_ = [
    {'_id': 'orders/213123',
     'contactEditor': {'name': 'Max Power',
                       'phone': '1234567'},
     'isCompleteDelivery': False,
     },
    {'_id': 'orders/2173823',
        'contactEditor': {'name': 'Michael'},
     }
]

def modkv(L, K):
    superset_ = set(key for dict_ in list_ for key in dict_[K])
    for dict_ in L:
        for key in superset_:
            dict_[K].setdefault(key, None)

superset = set(key for dict_ in list_ for key in dict_)

for dict_ in list_:
    for key in superset:
        dict_.setdefault(key, None)

for dict_ in list_:
    for k, v in dict_.items():
        if isinstance(v, dict):
            modkv(list_, k)

print(list_)

Output:

[{'_id': 'orders/213123', 'contactEditor': {'name': 'Max Power', 'phone': '1234567'}, 'isCompleteDelivery': False}, {'_id': 'orders/2173823', 'contactEditor': {'name': 'Michael', 'phone': None}, 'isCompleteDelivery': None}]
  • Related