Function to dynamically extract values from multiple nested dictionary in Python
Question:
The problem statement is to write a function which will take a input dictionary object and return a list of all the values, even in case of multi-level nested dictionaries inside the input dictionary object.
Example of such a nested dictionary below:
{
"f_name": "AKASH",
"s_name": "NASH",
"professional": {
"designation": "DE",
"company": "XYZ",
"place_of_work": {
"city": "BLR",
"state": "KA",
"country": "IN"
}
},
"personal_address": {
"city": "EKM",
"state": "KL",
"country": "IN"
}
}
I did write the below code and I am able to extract the dictionary values, even incase of one nested dictionary by means of manual conditional if statement.
def dic_values(x):
l =[]
l1 = []
if type(x) == dict:
for i in x:
if type(x[i]) != dict:
l.append(x[i])
elif type(x[i])== dict:
y = x[i]
for j in y:
l1.append(y[j])
else:
"Please input a dict object"
l.extend(l1)
return l
CASE 1:
On running the function with a dict object with one nested dictionary inside:
dic_values({"name":"AKASH","s_name":"NASH", "place":{"city":"BLR","state":"KA","country":"IN"}})
The Expected Output:
['AKASH', 'NASH', 'BLR', 'KA', 'IN']
CASE 2:
Like the below example, on having an input of multi-level nested dictionaries inside:
dic_values({"f_name":"AKASH","s_name":"NASH","professional":{"designation":"DE","company":"XYZ","place_of_work":{"city":"BLR","state":"KA","country":"IN"}}, "personal_address":{"city":"EKM","state":"KL","country":"IN"}})
The Output:
['AKASH','NASH','DE','XYZ', {'city': 'BLR', 'state': 'KA', 'country': 'IN'}, 'EKM', 'KL', 'IN']
Expected Output:
['AKASH','NASH','DE','XYZ', 'BLR', 'KA', 'IN', 'EKM', 'KL', 'IN']
QUESTION:
Say there were nested dictionaries present inside the input dictionary object. I would like to write a code, where the code dynamically checks for multi-level nested dictionary presence and executes. Like incase of CASE 2 Expected output.
Answers:
def all_dict_values(input_dict):
result = []
for value in input_dict.values():
if isinstance(value, dict):
result.extend(all_dict_values(value))
else:
result.append(value)
return result
modify your existing code to recursively call the dic_values:
def dic_values(x):
if not isinstance(x, dict):
return [x]
res = []
for v in x.values():
res.extend(dic_values(v))
return [v for v in res if not isinstance(v, dict)]
In case you are interested in doing this in a non-recursive way. You can maintaining a stack of dicts as you go. So long as the stack has dicts in it there are more values to find:
def dic_values(d):
assert isinstance(d, dict), "Please pass a dict"
values = [] # this will hold the values
stack = [d] # this should only contain dicts
while stack:
next_d = stack.pop()
for v in next_d.values():
if isinstance(v, dict):
stack.append(v) # put it back to process more
else:
values.append(v) # this a not dict, add it to the return list
return values
dic_values({"f_name":"AKASH","s_name":"NASH","professional":{"designation":"DE","company":"XYZ","place_of_work":{"city":"BLR","state":"KA","country":"IN"}}, "personal_address":{"city":"EKM","state":"KL","country":"IN"}})
# ['AKASH', 'NASH', 'EKM', 'KL', 'IN', 'DE', 'XYZ', 'BLR', 'KA', 'IN']
The problem statement is to write a function which will take a input dictionary object and return a list of all the values, even in case of multi-level nested dictionaries inside the input dictionary object.
Example of such a nested dictionary below:
{
"f_name": "AKASH",
"s_name": "NASH",
"professional": {
"designation": "DE",
"company": "XYZ",
"place_of_work": {
"city": "BLR",
"state": "KA",
"country": "IN"
}
},
"personal_address": {
"city": "EKM",
"state": "KL",
"country": "IN"
}
}
I did write the below code and I am able to extract the dictionary values, even incase of one nested dictionary by means of manual conditional if statement.
def dic_values(x):
l =[]
l1 = []
if type(x) == dict:
for i in x:
if type(x[i]) != dict:
l.append(x[i])
elif type(x[i])== dict:
y = x[i]
for j in y:
l1.append(y[j])
else:
"Please input a dict object"
l.extend(l1)
return l
CASE 1:
On running the function with a dict object with one nested dictionary inside:
dic_values({"name":"AKASH","s_name":"NASH", "place":{"city":"BLR","state":"KA","country":"IN"}})
The Expected Output:
['AKASH', 'NASH', 'BLR', 'KA', 'IN']
CASE 2:
Like the below example, on having an input of multi-level nested dictionaries inside:
dic_values({"f_name":"AKASH","s_name":"NASH","professional":{"designation":"DE","company":"XYZ","place_of_work":{"city":"BLR","state":"KA","country":"IN"}}, "personal_address":{"city":"EKM","state":"KL","country":"IN"}})
The Output:
['AKASH','NASH','DE','XYZ', {'city': 'BLR', 'state': 'KA', 'country': 'IN'}, 'EKM', 'KL', 'IN']
Expected Output:
['AKASH','NASH','DE','XYZ', 'BLR', 'KA', 'IN', 'EKM', 'KL', 'IN']
QUESTION:
Say there were nested dictionaries present inside the input dictionary object. I would like to write a code, where the code dynamically checks for multi-level nested dictionary presence and executes. Like incase of CASE 2 Expected output.
def all_dict_values(input_dict):
result = []
for value in input_dict.values():
if isinstance(value, dict):
result.extend(all_dict_values(value))
else:
result.append(value)
return result
modify your existing code to recursively call the dic_values:
def dic_values(x):
if not isinstance(x, dict):
return [x]
res = []
for v in x.values():
res.extend(dic_values(v))
return [v for v in res if not isinstance(v, dict)]
In case you are interested in doing this in a non-recursive way. You can maintaining a stack of dicts as you go. So long as the stack has dicts in it there are more values to find:
def dic_values(d):
assert isinstance(d, dict), "Please pass a dict"
values = [] # this will hold the values
stack = [d] # this should only contain dicts
while stack:
next_d = stack.pop()
for v in next_d.values():
if isinstance(v, dict):
stack.append(v) # put it back to process more
else:
values.append(v) # this a not dict, add it to the return list
return values
dic_values({"f_name":"AKASH","s_name":"NASH","professional":{"designation":"DE","company":"XYZ","place_of_work":{"city":"BLR","state":"KA","country":"IN"}}, "personal_address":{"city":"EKM","state":"KL","country":"IN"}})
# ['AKASH', 'NASH', 'EKM', 'KL', 'IN', 'DE', 'XYZ', 'BLR', 'KA', 'IN']