繁体   English   中英

递归中的全局变量。 Python

[英]Global variables in recursion. Python

好的,我使用的是 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))

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

  1. 如果我将变量 count 放在lenRecur函数之外,它第一次可以正常工作,但是如果我在不重新启动 python shell 的情况下再次尝试,则计数(显然)不会重新启动,因此它会不断添加。
  2. 如果我将count += 1行更改为count = 1它也可以工作,但输出(显然)是 1。

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

提前致谢!

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

在以这种方式工作之前,您需要使用 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

我认为你可以通过 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 )或猴子修补函数本身。

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

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

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

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:

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


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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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