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}]