Hi I have a complex dictionary of dictionaries:
dict1 = {
"CurrentSet": "/Sets/4332FF55-0430-456D-8DA5-55DDC3698723",
"Model": "MacBookPro11,2",
"NetworkServices": {
"36135701-9BA6-4005-F25A-BF75E9627244": {
"DNS": {},
"IPv4": {"ConfigMethod": "DHCP"},
"IPv6": {"ConfigMethod": "Automatic"},
"Interface": {
"DeviceName": "en0",
"Hardware": "Ethernet",
"Type": "Ethernet",
"UserDefinedName": "Ethernet",
},
"Proxies": {"ExceptionsList": ["*.local", "169.254/16"], "FTPPassive": 1},
"SMB": {},
"UserDefinedName": "Ethernet",
}
},
"Sets": {
"4332FF55-0430-456D-8DA5-55DDC3698723": {
"Network": {
"Global": {
"IPv4": {"ServiceOrder": ["36135701-9BA6-4005-F25A-BF75E9627244"]}
},
"Service": {
"36135701-9BA6-4005-F25A-BF75E9627244": {
"__LINK__": "/NetworkServices/36135701-9BA6-4005-F25A-BF75E9627244"
}
},
},
"UserDefinedName": "Automatic",
}
},
"System": {
"Network": {"HostNames": {"LocalHostName": "Tacos-MacBook-Pro"}},
"System": {
"ComputerName": "Taco’s MacBook Pro",
"ComputerNameEncoding": 0,
},
},
"__VERSION__": 20191120,
}
I am trying to write a python recursive function, to flatten each branch to its last string/or numeric/or list value.
So the desired output is :
CurrentSet|/Sets/F554332F-0430-456D-8DA5-55DDC3698723
Model|MacBookPro11,2
NetworkServices|35701361-F25A-4005-9BA6-BF75E9627244|DNS|
NetworkServices|35701361-F25A-4005-9BA6-BF75E9627244|IPv4|ConfigMethod|DHCP
NetworkServices|35701361-F25A-4005-9BA6-BF75E9627244|IPv6|ConfigMethod|Automatic
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|Interface|DeviceName|en0
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|Interface|Hardware|Ethernet
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|Interface|Type|Ethernet
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|Interface|UserDefinedName|Ethernet
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|Proxies|ExceptionsList|['*.local', '169.254/16']
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|Proxies|FTPPassive|1
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|SMB|
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|UserDefinedName|Ethernet
Sets|4332FF55-0430-456D-8DA5-55DDC3698723|Network|Global|IPv4|ServiceOrder|['36135701-9BA6-4005-F25A-BF75E9627244']
Sets|4332FF55-0430-456D-8DA5-55DDC3698723|Network|Service|36135701-9BA6-4005-F25A-BF75E9627244|__LINK__|/NetworkServices/36135701-9BA6-4005-F25A-BF75E9627244
Sets|4332FF55-0430-456D-8DA5-55DDC3698723|UserDefinedName|Automatic
System|Network|HostNames|LocalHostName|Tacos-MacBook-Pro
System|System|ComputerName|Taco’s MacBook Pro
System|System|ComputerNameEncoding|0
__VERSION__|20191120
Actual Output that I'm getting:
CurrentSet|/Sets/4332FF55-0430-456D-8DA5-55DDC3698723
Model|MacBookPro11,2
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|DNS|{}
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|IPv4|ConfigMethod|DHCP
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|IPv4|IPv6|ConfigMethod|Automatic
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|IPv4|IPv6|Interface|DeviceName|en0
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|IPv4|IPv6|Interface|Hardware|Ethernet
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|IPv4|IPv6|Interface|Type|Ethernet
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|IPv4|IPv6|Interface|UserDefinedName|Ethernet
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|IPv4|IPv6|Interface|Proxies|ExceptionsList|['*.local', '169.254/16']
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|IPv4|IPv6|Interface|Proxies|FTPPassive|1
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|IPv4|IPv6|Interface|Proxies|SMB|{}
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|IPv4|IPv6|Interface|Proxies|UserDefinedName|Ethernet
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|IPv4|IPv6|Interface|Proxies|Sets|4332FF55-0430-456D-8DA5-55DDC3698723|Network|Global|IPv4|ServiceOrder|['36135701-9BA6-4005-F25A-BF75E9627244']
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|IPv4|IPv6|Interface|Proxies|Sets|4332FF55-0430-456D-8DA5-55DDC3698723|Network|Global|IPv4|Service|36135701-9BA6-4005-F25A-BF75E9627244|__LINK__|/NetworkServices/36135701-9BA6-4005-F25A-BF75E9627244
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|IPv4|IPv6|Interface|Proxies|Sets|4332FF55-0430-456D-8DA5-55DDC3698723|Network|Global|IPv4|Service|36135701-9BA6-4005-F25A-BF75E9627244|UserDefinedName|Automatic
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|IPv4|IPv6|Interface|Proxies|Sets|4332FF55-0430-456D-8DA5-55DDC3698723|Network|Global|IPv4|Service|36135701-9BA6-4005-F25A-BF75E9627244|System|Network|HostNames|LocalHostName|Tacos-MacBook-Pro
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|IPv4|IPv6|Interface|Proxies|Sets|4332FF55-0430-456D-8DA5-55DDC3698723|Network|Global|IPv4|Service|36135701-9BA6-4005-F25A-BF75E9627244|System|Network|HostNames|System|ComputerName|Taco’s MacBook Pro
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|IPv4|IPv6|Interface|Proxies|Sets|4332FF55-0430-456D-8DA5-55DDC3698723|Network|Global|IPv4|Service|36135701-9BA6-4005-F25A-BF75E9627244|System|Network|HostNames|System|ComputerNameEncoding|0
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|IPv4|IPv6|Interface|Proxies|Sets|4332FF55-0430-456D-8DA5-55DDC3698723|Network|Global|IPv4|Service|36135701-9BA6-4005-F25A-BF75E9627244|System|Network|HostNames|System|__VERSION__|20191120
My code is:
def parse_dict(dict1, key_lst):
for key, val in dict1.items():
key_lst.append(key)
if isinstance(val, dict) and len(val) > 0:
parse_dict(val, key_lst)
else:
print('|'.join(map(str, key_lst)) '|' str(val))
key_lst.pop() # <-- Does this line need changes ?
key_lst = []
parse_dict(dict1, key_lst)
What am I doing wrong ? Please help
CodePudding user response:
Maybe something like this. walk()
is a recursive generator function that yields 2-tuples of "key trails" and their related values. Dicts, lists and tuples are iterated into; everything else is considered a leaf value.
def walk(item, trail=()):
if isinstance(item, (list, tuple)):
item = enumerate(item)
elif isinstance(item, dict):
item = item.items()
else:
raise TypeError(f"unsupported type")
for key, value in item:
new_trail = trail (key,)
if isinstance(value, (dict, list, tuple)):
yield from walk(value, new_trail)
else:
yield (new_trail, value)
for key, value in walk(dict1):
print("|".join(str(x) for x in key), value)
For your data, it prints out
CurrentSet /Sets/4332FF55-0430-456D-8DA5-55DDC3698723
Model MacBookPro11,2
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|IPv4|ConfigMethod DHCP
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|IPv6|ConfigMethod Automatic
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|Interface|DeviceName en0
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|Interface|Hardware Ethernet
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|Interface|Type Ethernet
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|Interface|UserDefinedName Ethernet
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|Proxies|ExceptionsList|0 *.local
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|Proxies|ExceptionsList|1 169.254/16
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|Proxies|FTPPassive 1
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|UserDefinedName Ethernet
Sets|4332FF55-0430-456D-8DA5-55DDC3698723|Network|Global|IPv4|ServiceOrder|0 36135701-9BA6-4005-F25A-BF75E9627244
Sets|4332FF55-0430-456D-8DA5-55DDC3698723|Network|Service|36135701-9BA6-4005-F25A-BF75E9627244|__LINK__ /NetworkServices/36135701-9BA6-4005-F25A-BF75E9627244
Sets|4332FF55-0430-456D-8DA5-55DDC3698723|UserDefinedName Automatic
System|Network|HostNames|LocalHostName Tacos-MacBook-Pro
System|System|ComputerName Taco�s MacBook Pro
System|System|ComputerNameEncoding 0
__VERSION__ 20191120
CodePudding user response:
Building on @AKX's approach and being more specific to this particular question's demands:
def walk(obj, trail=""):
if isinstance(obj, dict):
for key, value in obj.items():
yield from walk(value, f"{trail}|{key}")
else:
yield f"{trail}|{obj}".lstrip("|")
for line in walk(dict1):
print(line)
CurrentSet|/Sets/4332FF55-0430-456D-8DA5-55DDC3698723
Model|MacBookPro11,2
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|IPv4|ConfigMethod|DHCP
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|IPv6|ConfigMethod|Automatic
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|Interface|DeviceName|en0
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|Interface|Hardware|Ethernet
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|Interface|Type|Ethernet
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|Interface|UserDefinedName|Ethernet
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|Proxies|ExceptionsList|['*.local', '169.254/16']
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|Proxies|FTPPassive|1
NetworkServices|36135701-9BA6-4005-F25A-BF75E9627244|UserDefinedName|Ethernet
Sets|4332FF55-0430-456D-8DA5-55DDC3698723|Network|Global|IPv4|ServiceOrder|['36135701-9BA6-4005-F25A-BF75E9627244']
Sets|4332FF55-0430-456D-8DA5-55DDC3698723|Network|Service|36135701-9BA6-4005-F25A-BF75E9627244|__LINK__|/NetworkServices/36135701-9BA6-4005-F25A-BF75E9627244
Sets|4332FF55-0430-456D-8DA5-55DDC3698723|UserDefinedName|Automatic
System|Network|HostNames|LocalHostName|Tacos-MacBook-Pro
System|System|ComputerName|Taco’s MacBook Pro
System|System|ComputerNameEncoding|0
__VERSION__|20191120