Python递归不会产生期望的结果

时间:2015-01-28 10:00:16

标签: python recursion

我试图使用内置的len()函数找出字符串的长度。这是我的python代码:

increment = -1
def lenRecur(aStr):
    '''
    aStr: a string

    returns: int, the length of aStr
    '''
    global increment

    if aStr == '':
        return increment
    else:
        increment += 1
        return lenRecur (aStr[increment:])
print lenRecur ("abcdefq")

我期待的结果是7,但我得到的是4.我意识到当increment变为2时,传递给lenRecur (aStr[increment:])的值为"defq"。这意味着aStr[2:]被评估为"defq"而不是"cdefq"

为什么会这样?

3 个答案:

答案 0 :(得分:3)

您的功能不应该依赖于外部变量。

def lenRecur(aStr):
    '''
    aStr: a string

    returns: int, the length of aStr
    '''
    if aStr == '':
        return 0
    else:
        return 1 + lenRecur(aStr[1:])


print lenRecur("abcdefq")

答案 1 :(得分:0)

作为另一种选择,你可以这样写:

def lenRecur(aStr):
    return _lenRecur(aStr, 0)

def _lenRecur(aStr, acc):
    if not aStr:
        return acc

    return _lenRecur(aStr[1:], acc+1)

@gboffi在他的回答中注意到,Python中通常接受使用默认参数而不是使用辅助函数:

def lenRecur(aStr, acc = 0):
    if not aStr:
        return acc

    return lenRecur(aStr[1:], acc+1)

一种形式或另一种形式的选择将取决于您希望/不希望允许被调用者将初始累加器值设置为0以外的其他值。

无论如何,这里有趣的一点是使用累加器作为第二个参数。这样,你有适当的tail recursion。不幸的是,Python没有对此进行适当优化。但这是一个好习惯,因为许多其他语言都有这样的优化。如果你有一天切换到功能性编程语言,这将是一项必修技能。

答案 2 :(得分:0)

一个常见的习惯用法是使用默认参数:

>>> def l(s, c=0): return l(s[1:], c+1) if s else c

这种解决方案适用于任何可以切片的

>>> l('pip')
3
>>> l([1,2,3])
3
>>> l('')
0
>>> l([])
0
>>>