简体   繁体   中英

Odd behavior of function return

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.

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 .

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().

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM