Reputation: 9454
I'm still a novice in Python
and currently trying out things with dictionaries
. I'm having a nested dictionary
which would look like:
nestedDic = {'FROM': {'SOME TEXT FROM': ['CHILD1', 'CHILD2']}}
and I was able to print them by iterating through the child nodes.
def print_nested(val, nesting = -5):
if type(val) == dict:
#print('')
nesting += 5
for k in val:
print(end='')
print(k)
print_nested(val[k],nesting)
else:
print(val)
But the output looks like:
But the output I need is:
FROM SOME TEXT FROM CHILD1 CHILD2
Where am I going wrong? Any help could be appreciated.
Upvotes: 3
Views: 1235
Reputation: 8730
@Kulasangar, your question is very interesting and nice. I thought to solve your problem using recursion.
It works fine with your provided nested input dictionary and many other nested input dictionary containing other data structures like list, tuple, set, int, float etc.
I thought what if you will have int, float, complex, long, tuple as keys and what if you will have any iterable like set, list, tuple as items in the corresponding value.
set and dictionary are unordered types so it is better if you will limit their length to 1 item. That is why I have limited their length to 1 to get the words of the final string in sequence.
Eg. for the below INPUT dictionary.
nestedDic = {
('DATA', 'ANALYSIS'): {'IS': {'VERY': {'VERY': ['IMPORTANT.']}}},
4+4j: ['IS', ('A', 'Complex', 'number.')],
3.14: {
'IS': {'VALUE': {
'OF PI': {
'(A MATHEMATICAL': ['CONSTANT).']
}
}
}
},
1729: ['IS', 'KNOWN', ('AS', ('RAMANUJAN NUMBER.'))], # sets can only contain immutable values
'I AM RISHIKESH': {
'AGRAWANI.': 'A GREAT FAN',
('OF', 'PYTHON'): (' AND MATHEMATICS.', {'I WAS BORN ON'}),
1992: 'AND I LIKE THIS YEAR.'
}
}
You will expect the below string as OUTPUT.
DATA ANALYSIS IS VERY VERY IMPORTANT. (4+4j) IS A Complex number. 3.14 IS VALUE OF PI (A MATHEMATICAL CONSTANT). 1729 IS KNOWN AS RAMANUJAN NUMBER. I AM RISHIKESH AGRAWANI. A GREAT FAN OF PYTHON AND MATHEMATICS. I WAS BORN ON 1992 AND I LIKE THIS YEAR.
Now, please have a look at the below Python code. Here I have 2 recursive functions.
get_string() works on list, tuple, and set. It also works if dictionary's key is a tuple.
get_string_from_nested_dict() recursively creates a string. If it finds any key as tuple then it calls another recursive function get_string() to get exact string of words (instead of using the tuple itself).
def get_string(l):
s = ''
for elem in l:
if type(elem) is str:
s += elem + ' '
elif type(elem) is tuple or type(elem) is list or type(elem) is set: # tuple, list, set
s += get_string(elem) + ' '
else: # int,float, complex, long
s += str(s) + ' '
return s.strip() # Remove leading or trailing white spaces
def get_string_from_nested_dict(nestedDic):
s = ''
for key in nestedDic:
if s is str:
s += key + ' '
elif type(key) is tuple:
s += get_string(key) + ' '
else: # int, complex, float, long
s += str(key) + ' '
item = nestedDic[key]
if type(item) is dict: # dict
s += get_string_from_nested_dict(nestedDic[key]) + ' '
elif type(item) is tuple or type(item) is list or type(item) is set: # list, tuple, set
s2 = get_string(item)
s += s2 + ' '
else: # int, float, comples, long
s += str(item) + ' '
return s.strip() # Remove leading or trailing white spaces
# Start
if __name__ == "__main__":
# *** TEST CASE 1 ***
nestedDic = {'FROM': {'SOME TEXT FROM': ['CHILD1', 'CHILD2']}}
s = get_string_from_nested_dict(nestedDic)
print(s, '\n') # FROM SOME TEXT FROM CHILD1 CHILD2
# *** TEST CASE 2 ***
nestedDic2 = {'HELLO,': {
'IT IS': ['VERY', {'NICE', 'PROGRAM.'}],
'PYTHON': {'IS', 'SUPER.'},
'YOU': ('CAN USE IT', 'FOR', ['DATA SCIENCE.'])
}
}
s2 = get_string_from_nested_dict(nestedDic2)
print(s2, '\n')
# *** TEST CASE 3 ***
nestedDic3 = {
('DATA', 'ANALYSIS'): {'IS': {'VERY': {'VERY': ['IMPORTANT.']}}},
4+4j: ['IS', ('A', 'Complex', 'number.')],
3.14: {
'IS': {'VALUE': {
'OF PI': {
'(A MATHEMATICAL': ['CONSTANT).']
}
}
}
},
1729: ['IS', 'KNOWN', ('AS', ('RAMANUJAN NUMBER.'))], # sets can only contain immutable values
'I AM RISHIKESH': {
'AGRAWANI.': 'A GREAT FAN',
('OF', 'PYTHON'): (' AND MATHEMATICS.', {'I WAS BORN ON'}),
1992: 'AND I LIKE THIS YEAR.'
}
}
s3 = get_string_from_nested_dict(nestedDic3)
print(s3)
Upvotes: 1
Reputation: 1343
This is one possible solution but valid only in cases like yours:
output = []
def print_nested(val):
if type(val) == dict:
for k, v in val.items():
output.append(k)
print_nested(v)
elif type(val) == list:
for k in val:
output.append(k)
print_nested(k)
nestedDic = {'FROM': {'SOME TEXT FROM': ['CHILD1', 'CHILD']}}
print_nested(nestedDic)
output = " ".join(output)
print(output)
Upvotes: 0
Reputation: 1425
def printNestedDict(d: dict):
for k, v in d.items():
if (isinstance(v, dict)):
print(k, end = " ")
printNestedDict(v)
continue
if (any(isinstance(v, t) for t in [tuple, list])):
print(k, *v, sep = " ", end = " ")
continue
print(k, v, sep = " ", end = " ")
Does exactly as you expected, checks for collections and will output each one.
Upvotes: 1
Reputation: 7859
This one should do your work:
nestedDict = {'FROM': {'SOME TEXT FROM': ['CHILD1', 'CHILD2']}}
def printDict(inDict):
print(k,end=" ")
for k,v in inDict.items():
if type(v) == dict:
printDict(v)
elif type(v) == list:
for i in v:
print(i, end=" ")
else:
print(v, end=" ")
Output:
FROM SOME TEXT FROM CHILD1 CHILD2
Upvotes: 3
Reputation: 1916
Rather than print(end=' '); print(k)
, you want print(k, end=' ')
. Changing kwargs like that in a call to a function doesn't leave them set the next time you call it.
Upvotes: 2