【问题标题】:Python recursive function not returning valuePython递归函数不返回值
【发布时间】:2014-06-04 10:46:26
【问题描述】:

这是我在这里的第一个问题,如果我写的太多,我最诚挚的歉意,并提前非常感谢您的阅读。

问题:

我写了一个函数,如果有必要,它应该调用自己 x 次,如果不成功则什么也不返回。但是,当函数似乎成功时,它仍然返回 None。

背景:我有许多代表 2009 年月份的目录。但并非所有月份都存在,因此如果是这种情况,我想获取上个月,检查该月的目录是否存在,如果不继续返回 1 个月,最多 6 个月。

您在下面看到 date_tag 中的月份 09,这在我的测试用例中不存在。 08 或 07 也没有。因此,函数应该返回 06,但它返回 None。

import pdb
import generate_months_module
import os

date_tag = '2000/2000/2009/09'
tree_location = '/Users/kelly/Documents/projects/komm/data/directory-tree/'

def iterateOverMonths(date_tag, x):
    if x <= 0:
        return_string = 'no dates found'
        return return_string
    else:
        new_date = generate_months_module.handleDateShifts(date_tag)[1]
        print '\tNEW DATE after calling handleDateShifts' + new_date
        full_path = tree_location + '/' + new_date
        if checkDirectoryExistance(full_path) == True:
            print '\t'+ full_path + ' is a real path'
            return full_path
        else:
            print 'dir does not exist'                                                                                                                       
            iterateOverMonths(new_date, x-1)

def checkDirectoryExistance(dir_path):
    "check if a directory exists, return true or false"
    if os.path.isdir(dir_path) == True:
        return True
    else:
        return False

print iterateOverMonths(date_tag, 6)

generate_months_module.handleDateShifts 应该只是获取上个月并返回它。 (这适用于其他测试用例,所以我非常怀疑问题出在这里!)

然后我的输出是:

6
    NEW DATE after calling handleDateShifts2000/2000/2009/08
    dir does not exist
5
    NEW DATE after calling handleDateShifts2000/2000/2009/07
    dir does not exist
4
    NEW DATE after calling handleDateShifts2000/2000/2009/06

    /Users/kelly/Documents/projects/komm/data/directory-tree/2000/2000/2009/06 is a real path

    returning full path
    None

当我在“return full_path”之前使用 pdb.set_trace() 时,似乎再次调用了该函数,尽管 IF 子句为 True,因此覆盖了我想要返回的“full_path”变量。

为什么没有返回路径“/Users/kelly/Documents/projects/komm/data/directory-tree/2000/2000/2009/06”??

导入函数:

如果有人对此感兴趣并想重新创建它,handleDateShifts 函数如下(抱歉,有点乱):

def handleDateShifts(corpus_date_string):
    "get background corpus date strings ALSO call this function if month does not exist and need to go back even further"
    century, decade, year, month = corpus_date_string.split('/')
    if month == '01' or month == '02':
        #handle date boundaries which can affect year, decade and cent                                                   
        background_mo_1 = '11'
        background_mo_2 = '12'
        millenium_shift = re.search('[1-9][0][0][0]$', year)
        century_shift = re.search('[1-9][0][0]$', year)
        decade_shift = re.search('[1-9][0]$',year)
        if century_shift or millenium_shift:
            century = int(year) - 100
            decade = int(year) - 10
            year = int(year) - 1
        elif decade_shift:
            decade = int(year) - 10
            year = int(year) - 1
        elif not decade_shift and not century_shift:
            year = int(year) - 1
        background_1_string = str(century) +'/'+ str(decade) +'/'+ str(year) +'/'+ str(background_mo_1)
        background_2_string = str(century) +'/'+ str(decade) +'/'+ str(year) +'/'+ str(background_mo_2)
    else: #the cent/dec/year can stay the same                                                                           
        background_mo_1 = int(month) - 2
    background_mo_2 = int(month) - 1
        if len(str(background_mo_1)) == 1:
            background_mo_1 = '0' + str(background_mo_1)
        if len(str(background_mo_2)) == 1:
            background_mo_2 = '0' + str(background_mo_2)
        background_1_string = str(century) +'/'+ str(decade) +'/'+ str(year) +'/'+ str(background_mo_1)
        background_2_string = str(century) +'/'+ str(decade) +'/'+ str(year)+'/'+ str(background_mo_2)
    return background_1_string, background_2_string

【问题讨论】:

  • 请仔细检查iterateOverMonths()中的缩进
  • 谢谢!我修复了它,只是网站上的一个错字。

标签: python function recursion return-value


【解决方案1】:

你没有在这个分支中返回任何东西(你的结果丢失了):

    else:
        print 'dir does not exist'                                                                                                                       
        iterateOverMonths(new_date, x-1)

如果函数在没有明确return &lt;smth&gt; 的情况下运行它,则返回None

【讨论】:

  • 好的,我明白了...我是递归函数的新手(显然),所以我不确定如何在这个 else 语句中返回。我添加了“return full_path”,但它给了我“..../2000/2000/2009/08”,这是不正确的:S
  • 需要返回递归调用的返回值,即return iterateOverMonths(new_date, x-1)
  • 耶!这行得通。好的,太棒了,非常感谢,你让我很开心。