Reputation: 53
I've spent many hours searching through all the "my function returns none" and "nested dict search" messages and none apply specifically nor do any resolve my issue.
I made a function to search a nested dictionary and return the path. This works great! I can print the results from within the function but the return immediately below the print returns None. Maybe I've been looking at it too long and it probably is right in front of my face but I'm just not seeing what's wrong here. Here's my complete code:
def search(v, searchterm, vid, path=(),):
if isinstance(v, dict):
for k, v2 in v.items():
p2 = path + ('{}'.format(k),)
search(v2, searchterm, vid, p2)
else:
if searchterm in v:
a = {}
a[0] = path
a[1] = v[vid]
print(a)
return(a)
def main():
mydata = {}
mydata[1] = {}
mydata[1][1] = 'data-1-1','reason-1-1','notes-1-1'
mydata[1][2] = 'data-1-2','reason-1-2','notes-1-2'
mydata[1][3] = 'data-1-3','reason-1-3','notes-1-3'
mydata[1][4] = 'data-1-4','reason-1-4','notes-1-4'
mydata[1][5] = 'data-1-5','reason-1-5','notes-1-5'
mydata[1][6] = 'data-1-6','reason-1-6','notes-1-6'
mydata[1][7] = 'data-1-7','reason-1-7','notes-1-7'
mydata[1][8] = 'data-1-8','reason-1-8','notes-1-8'
mydata[1][9] = 'data-1-9','reason-1-9','notes-1-9'
mydata[1][10] = 'data-1-10','reason-1-10','notes-1-10'
mydata[2] = {}
mydata[2][1] = 'data-2-1','reason-2-1','notes-2-1'
mydata[2][2] = 'data-2-2','reason-2-2','notes-2-2'
mydata[2][3] = 'data-2-3','reason-2-3','notes-2-3'
mydata[2][4] = 'data-2-4','reason-2-4','notes-2-4'
mydata[2][5] = 'data-2-5','reason-2-5','notes-2-5'
mydata[2][6] = 'data-2-6','reason-2-6','notes-2-6'
mydata[2][7] = 'data-2-7','reason-2-7','notes-2-7'
mydata[2][8] = 'data-2-8','reason-2-8','notes-2-8'
mydata[2][9] = 'data-2-9','reason-2-9','notes-2-9'
mydata[2][10] = 'data-2-10','reason-2-10','notes-2-10'
b = search(mydata,'reason-2-4', 2)
print(b)
if __name__ == '__main__':
main()
The results:
{0: ('2', '4'), 1: 'notes-2-4'}
None
You can see the print works great from within the function but the return and print from main returns None. I've been programming in Python for a few years now with many functions, classes and methods with returns written but this one has me stuck.
Upvotes: 1
Views: 75
Reputation: 13079
You're making a recursive call and the print
statement is issued in the nested call. However, the return value of search
is not used, that's why it never reaches the main
function.
Below, I have added a nested
variable that is checked, and if anything was found that is actually returned.
def search(v, searchterm, vid, path=(),):
if isinstance(v, dict):
for k, v2 in v.items():
p2 = path + ('{}'.format(k),)
nested = search(v2, searchterm, vid, p2)
if nested:
# before, nothing was ever returned here
return nested
else:
if searchterm in v:
a = {}
a[0] = path
a[1] = v[vid]
print(a)
return(a)
Not related, but in here you could make great use of the powerful dict literals of python
mydata = {
1: {
1: ('data-1-1', 'reason-1-1', 'notes-1-1'),
2: ('data-1-2', 'reason-1-2', 'notes-1-2')
2: {
1: ('data-2-1', 'reason-2-1', 'notes-2-1'),
2: ('data-2-2', 'reason-2-2', 'notes-2-2')
}
Also, if all your dictionary keys are int, you might as well use a list
.
Upvotes: 4
Reputation: 990
Out of the 3 paths in search(), only 1 returns something:
def search(v, searchterm, vid, path=(),):
if isinstance(v, dict):
# Path 1
for k, v2 in v.items():
p2 = path + ('{}'.format(k),)
search(v2, searchterm, vid, p2)
# Nothing returned here
else:
if searchterm in v:
# Path 2
a = {}
a[0] = path
a[1] = v[vid]
print(a)
return(a)
else:
# Path 3
# Nothing returned here
Path 1 calls Path 2 which explains why there is something printed but not returned to main().
Upvotes: 2