递归中的全局变量。蟒蛇

时间:2013-06-27 11:32:17

标签: python variables recursion global

好的,我正在使用Python 2.7.3,这是我的代码:

def lenRecur(s): 

    count = 0

    def isChar(c):
        c = c.lower()
        ans=''
        for s in c:
            if s in 'abcdefghijklmnopqrstuvwxyz':
                ans += s
        return ans

    def leng(s):
        global count
        if len(s)==0:
            return count
        else:
            count += 1
            return leng(s[1:])

    return leng(isChar(s))

我正在尝试修改count函数中的变量leng。以下是我尝试过的事情:

  1. 如果我将变量count放在lenRecur函数之外,它第一次运行正常,但是如果我再次尝试而不重新启动python shell,则计数(显然)不会重新启动,因此它会不断添加。 / LI>
  2. 如果我更改count += 1的{​​{1}}行,它也可以,但输出(显然)是一个。
  3. 所以,我的目标是使用递归来获取字符串的长度,但我不知道如何跟踪字母的数量。我搜索了有关全局变量的信息,但我仍然陷入困境。我不知道我还没有理解它,或者我的代码中有问题。

    提前致谢!

6 个答案:

答案 0 :(得分:16)

count中的{p> lenRecur 全球。它是一个范围变量。

在以这种方式完成工作之前,您需要使用Python 3;您正在寻找添加到Python 3中的nonlocal statement

在Python 2中,您可以通过使用count的可变(例如列表)来解决此限制:

def lenRecur(s): 

    count = [0]

    # ...

    def leng(s):
        if len(s)==0:
            return count[0]
        else:
            count[0] += 1
            return lenIter(s[1:])

现在你不再改变count这个名字了;它保持不变,它一直指的是同一个列表。您所做的只是改变count列表中第一个包含的元素。

另一种'拼写'是使count成为一个函数属性:

def lenRecur(s): 

    # ...

    def leng(s):
        if len(s)==0:
            return leng.count
        else:
            leng.count += 1
            return lenIter(s[1:])

    leng.count = 0

现在count不再是lenRecur()的本地人;它已成为不变的lenRecur()函数的一个属性。

对于你的具体问题,你实际上是在思考问题。只需让递归进行求和:

def lenRecur(s):
    def characters_only(s):
        return ''.join([c for c in s if c.isalpha()])

    def len_recursive(s):
        if not s:
            return 0
        return 1 + len_recursive(s[1:])

    return len_recursive(characters_only(s))

演示:

>>> def lenRecur(s):
...     def characters_only(s):
...         return ''.join([c for c in s if c.isalpha()])
...     def len_recursive(s):
...         if not s:
...             return 0
...         return 1 + len_recursive(s[1:])
...     return len_recursive(characters_only(s))
... 
>>> lenRecur('The Quick Brown Fox')
16

答案 1 :(得分:6)

我认为你可以将计数作为第二个参数传递

def anything(s):
    def leng(s, count):
        if not s:
            return count
        return leng(s[1:], count + 1)

    return leng(isChar(s), 0)

这应该比将外部作用域中的对象静音更好,例如使用可变对象(listdict)或猴子修补功能本身。

答案 2 :(得分:1)

您需要使变量计数为

之类的函数变量
def lenRecur(s):
    lenRecur.count = 0

但是,我发现代码存在一些问题。

1)如果你试图通过递归找到字符串中的字母数量,那么这个会做:

def lenRecur(s):
    def leng(s, count = 0):
            if not s:
                    return count
            else:
                    count += int(s[0].isalpha())
                    return leng(s[1:], count)
    return leng(s)

但我仍然希望有一个函数来执行任务,就像根本没有leng方法一样。

2)如果您的目标只是找到字符串中的字母数,我更喜欢列表理解

def alphalen(s):
    return sum([1 for ch in s if ch.isalpha()])

如果这不是学习目的,我建议你避免递归。因为,该解决方案不能用于更大的字符串(比方说,从文件内容中查找字母数)。您可能会遇到超过最大递归深度的RunTimeError。

即使您可以通过setrecursionlimit函数设置递归深度来解决这个问题,我建议您采用其他简单的方法。有关设置recursionlimit here的更多信息。

答案 3 :(得分:0)

如果要将其用作全局变量,请在所有函数定义之外定义它:

count = 0
def lenRecur(s): 

或将其定义为函数属性:

def lenRecur(s): 
    lenRecur.count = 0
    def isChar(c):

这已在py3.x中修复,您可以使用nonlocal语句:

def leng(s):
    nonlocal count
    if len(s)==0:

答案 4 :(得分:0)

你不需要数数。以下功能应该有效。


    def leng(s):
        if not s:
            return 0
        return 1 + leng(s[1:])

答案 5 :(得分:-2)

递归中的全局变量非常棘手,因为深度达到其最后一个状态并开始返回到第一次递归调用,局部变量的值发生变化,因此我们使用全局变量。全局变量的问题在于,当您多次运行 func 时,全局变量不会重置。