Reputation: 1203
I have a python object that looks like this. I am trying to parse this object and turn it to a human readable string which I need to put in the logs. How can I recursively loop through this considering the object could be nested dictionaries or nested lists or dictionaries inside lists inside dictionaries etc.
{"plugins":
[
{"Chrome PDF Viewer": "mhjfbmdgcfjbbpaeojofohoefgiehjai"},
{"Chrome PDF Viewer": "internal-pdf-viewer"},
{"Native Client": "internal-nacl-plugin"},
{"Shockwave Flash": "PepperFlashPlayer.plugin"},
{"Widevine Content Decryption Module": "widevinecdmadapter.plugin"}
]
}
I want to possibly serialize the above to look something like this
"plugins:
Chrome PDF Viewer": "mhjfbmdgcfjbbpaeojofohoefgiehjai,
Chrome PDF Viewer": "internal-pdf-viewer,
Native Client": "internal-nacl-plugin,
Shockwave Flash": "PepperFlashPlayer.plugin,
Widevine Content Decryption Module": "widevinecdmadapter.plugin"
My code so far [this works for nested dictionaries but I am not sure how I can alter this to support lists in the above object]:
result_str = ""
def dictionary_iterator(results):
global result_str
for key, value in results.items():
if isinstance(value, dict):
result_str = result_str + key + ": \n \t"
dictionary_iterator(value)
else:
result_str = result_str + key + ": " + str(value) + "\n"
return result_str
I have looked over possible answers but could not find a solution.
Upvotes: 2
Views: 2929
Reputation: 18106
You need an elif-condition in case of type == list and a indentation tracker:
data = {"plugins":
[
{"Chrome PDF Viewer": "mhjfbmdgcfjbbpaeojofohoefgiehjai"},
{"Chrome PDF Viewer": "internal-pdf-viewer"},
{"Native Client": "internal-nacl-plugin"},
{"Shockwave Flash": "PepperFlashPlayer.plugin"},
{"Widevine Content Decryption Module": "widevinecdmadapter.plugin"}
],
"anotherLevel":
{
"sublevel": [
{'item1': 'value1'}
]
}
}
result_str = ""
def dictionary_iterator(indent, data):
global result_str
if isinstance(data, dict):
for key, value in data.items():
result_str += indent*'\t' + key + '\n'
indent = indent + 1
dictionary_iterator(indent, value)
elif isinstance(data, list):
for item in data:
if isinstance(item, dict) and len(list(item.keys())) == 1:
key = list(item.keys())[0]
value = item[key]
result_str += indent*'\t' + key + ': ' + value + '\n'
else:
indent = indent + 1
dictionary_iterator(indent, item)
return result_str
if __name__ == '__main__':
print(dictionary_iterator(0, data))
That will print out:
plugins
Chrome PDF Viewer: mhjfbmdgcfjbbpaeojofohoefgiehjai
Chrome PDF Viewer: internal-pdf-viewer
Native Client: internal-nacl-plugin
Shockwave Flash: PepperFlashPlayer.plugin
Widevine Content Decryption Module: widevinecdmadapter.plugin
anotherLevel
sublevel
item1: value1
Upvotes: 1
Reputation: 7228
The formatting might be a bit off
def humanizer(input, result=''):
if type(input) == dict:
for k, v in input.items():
if type(v) == str:
result += '%s:%s\n\t' % (str(k), str(v))
elif type(v) in (dict, list):
result += '%s:\n\t' % str(k)
result = humanizer(v, result)
result += '\n\t'
elif type(input) == list:
for item in input:
if type(item) == str:
result += item
continue
result = humanizer(item, result) + '\n\t'
else:
result += input + '\n\t'
return result
Result:
plugins:
Chrome PDF Viewer:mhjfbmdgcfjbbpaeojofohoefgiehjai
Chrome PDF Viewer:internal-pdf-viewer
Native Client:internal-nacl-plugin
Shockwave Flash:PepperFlashPlayer.plugin
Widevine Content Decryption Module:widevinecdmadapter.plugin
Upvotes: 2