12

好的,我使用的是 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 的情况下再次尝试,则计数(显然)不会重新启动,所以它会继续添加。
  2. 如果我改变它也可以count += 1工作count = 1,但输出(显然)是一个。

所以,我的目标是使用递归来获取字符串的长度,但我不知道如何跟踪字母的数量。我搜索了有关全局变量的信息,但我仍然卡住了。我不知道我是否还没有理解它,或者我的代码是否有问题。

提前致谢!

4

6 回答 6

28

countinlenRecur不是全局的它是一个作用域变量。

您需要先使用 Python 3,然后才能以这种方式工作;您正在寻找添加到 Python 3的nonlocal语句。

在 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
于 2013-06-27T11:35:58.847 回答
9

我认为您可以将 count 作为第二个参数传递

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

    return leng(isChar(s), 0)

这应该比从外部范围屏蔽对象更好,例如使用可变对象(listdict)或猴子修补函数本身。

于 2013-06-27T11:43:43.277 回答
3

您需要使变量计数成为函数变量,例如

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 函数设置递归深度来解决此问题,但我建议您采用其他简单的方法。有关在此处设置递归限制的更多信息。

于 2013-06-27T12:22:52.530 回答
1

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

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:
于 2013-06-27T11:37:41.403 回答
0

你不需要计数。下面的功能应该可以工作。


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

于 2013-06-27T11:42:09.167 回答
-2

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

于 2021-05-17T09:10:05.140 回答