Reputation: 203
I would like to print nested hash in Python, from this:
example_dict = {
'key1' : 'value1',
'key2' : {
'key2a': 'value2a'
},
'key3' : {
'key3a': {
'key3aa': 'value3aa',
'key3ab': 'value3ab',
'key3ac': 'value3ac'
},
'key3b': [
'value3b1',
'value3b2'
]
},
}
to something like this:
key1 value1
key2 key2a value2a
key3 key3a key3aa value3aa
key3 key3a key3ab value3ab
key3 key3a key3ac value3ac
key3 key3b value3b1
key3 key3b value3b2
I am not really familiar with Python, and after couple hours I'm still stuck.
I currently working on this function:
def recursive(src, res, line = ''):
if isinstance(src, dict):
for key, value in src.items():
line += str(' ' + key)
recursive(value, res, line)
elif isinstance(src, list):
for litem in src:
recursive(litem, res, line)
else:
line += str(' ' + str(src))
res.append(line)
I'm trying to add each line to a list to be able to use it later, but I think I don't have the right aproach with my shared variable (line), because at each dict the recursive call is made with one more dict key from the same level of depth, so I got this :
key3 key3a key3aa value3aa
key3 key3a key3aa key3ac value3ac
key3 key3a key3aa key3ac key3ab value3ab
key3 key3a key3b value3b1
key3 key3a key3b value3b2
key3 key2 key2a value2a
key3 key2 key1 value1
What would be a Pythonic way to do this?
Upvotes: 1
Views: 90
Reputation: 49814
Using a generator (yield
statement) you can do that recursively like:
def recursive(src, so_far=()):
if isinstance(src, dict):
for key, value in src.items():
yield from recursive(value, so_far + (key,))
elif isinstance(src, list):
for item in src:
yield from recursive(item, so_far)
else:
yield ' '.join(so_far + (src,))
One thing to note is the need to re-yield the results from the generator that was recursed into. That is done here using:
yield from recursive(item, so_far)
Which is equivalent to:
for i in recursive(item, so_far):
yield i
example_dict = {
'key1': 'value1',
'key2': {
'key2a': 'value2a'
},
'key3': {
'key3a': {
'key3aa': 'value3aa',
'key3ab': 'value3ab',
'key3ac': 'value3ac'
},
'key3b': [
'value3b1',
'value3b2'
]
},
}
for line in recursive(example_dict):
print(line)
key1 value1
key2 key2a value2a
key3 key3a key3aa value3aa
key3 key3a key3ab value3ab
key3 key3a key3ac value3ac
key3 key3b value3b1
key3 key3b value3b2
Upvotes: 7
Reputation: 3898
Pretty straightforward recursive implementation.
def pr(t, pref=''):
for k, v in t.items():
if isinstance(v, dict):
pr(v, pref=(pref + k + ' '))
elif isinstance(v, list):
for el in v:
if isinstance(el, str):
print(pref + ' ' + k + ' ' + el)
else:
pr(el, pref=k + ' ')
else:
print(pref + ' ' + k + ' ' + v)
Upvotes: 0
Reputation: 1645
I got this to work, but its a bit hacky, using append
adds one element, and extend
adds all elements in a list. Hope it helps:
def recursive(src, start=""):
lst = []
for k, v in src.items():
new_start = "{} {}".format(start, k)
if isinstance(v, dict):
lst.extend(recursive(v, start=new_start))
elif isinstance(v, list):
lst.extend("{}: {}".format(new_start[1:] , val) for val in v)
else:
lst.append("{}: {}".format(new_start[1:] , v))
return lst
items = recursive(example_dict)
for item in items:
print(item)
Output:
key1: value1
key2 key2a: value2a
key3 key3a key3aa: value3aa
key3 key3a key3ab: value3ab
key3 key3a key3ac: value3ac
key3 key3b: value3b1
key3 key3b: value3b2
Upvotes: 1