简体   繁体   English

递归中的全局变量。 Python

[英]Global variables in recursion. Python

OK, i'm using Python 2.7.3 and here is my code:好的,我使用的是 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))

I'm trying to modify the variable count inside the leng function.我正在尝试修改leng函数内的变量count Here are the things that I've tried:以下是我尝试过的事情:

  1. If I put the variable count outside the lenRecur function it works fine the first time, but if I try again without restarting python shell, the count (obviously) doesn't restart, so it keeps adding.如果我将变量 count 放在lenRecur函数之外,它第一次可以正常工作,但是如果我在不重新启动 python shell 的情况下再次尝试,则计数(显然)不会重新启动,因此它会不断添加。
  2. If I change the count += 1 line for count = 1 it also works, but the output is (obviously) one.如果我将count += 1行更改为count = 1它也可以工作,但输出(显然)是 1。

So, my goal here is to get the length of the string using recursion, but I don't know how to keep track of the number of letters.所以,我的目标是使用递归获取字符串的长度,但我不知道如何跟踪字母的数量。 I've searched for information about global variables, but I am still stuck.我已经搜索了有关全局变量的信息,但仍然卡住了。 I don't know if i haven't understood it yet, or if I have a problem in my code.不知道是我还没看懂,还是我的代码有问题。

Thanks in advance!提前致谢!

count in lenRecur is not a global. lenRecur count不是全局的。 It is a scoped variable.它是一个作用域变量。

You'll need to use Python 3 before you can make that work in this way;在以这种方式工作之前,您需要使用 Python 3; you are looking for the nonlocal statement added to Python 3.您正在寻找添加到 Python 3 的nonlocal语句

In Python 2, you can work around this limitation by using a mutable (such as a list) for count instead:在 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:])

Now you are no longer altering the count name itself;现在您不再改变count名称本身; it remains unchanged, it keeps referring to the same list.它保持不变,它一直引用同一个列表。 All you are doing is altering the first element contained in the count list.您所做的只是更改count列表中包含的第一个元素。

An alternative 'spelling' would be to make count a function attribute:另一种“拼写”是使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

Now count is no longer local to lenRecur() ;现在count不再是lenRecur()本地的; it has become an attribute on the unchanging lenRecur() function instead.它已成为不变的lenRecur()函数的一个属性。

For your specific problem, you are actually overthinking things.对于你的具体问题,你实际上是想多了。 Just have the recursion do the summing:只需让递归进行求和:

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))

Demo:演示:

>>> 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

I think You can pass count as second argument我认为你可以通过 count 作为第二个参数

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

    return leng(isChar(s), 0)

this should work better than muting objects from outer scope such as using mutable objects ( list or dict ) or monkey-patching function itself for example.这应该比从外部范围静音对象更好,例如使用可变对象( listdict )或猴子修补函数本身。

You need to make the variable count a function variable like您需要使变量计数成为函数变量,例如

def lenRecur(s):
    lenRecur.count = 0

However, I see a few problems with the code.但是,我发现代码存在一些问题。

1) If you are trying to find the number of alphabets in a string through recursion, this one will do: 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)

But still I would prefer having a single function to do the task, like there will be no leng method at all.但我仍然希望有一个单一的功能来完成任务,就像根本没有 leng 方法一样。

2) If your goal is just to find the number of alphabets in a string, I would prefer list comprehension 2)如果您的目标只是找到字符串中的字母数,我更喜欢列表理解

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

If this is anything other than learning purpose, I suggest you to avoid recursion.如果这不是学习目的,我建议你避免递归。 Because, the solution cannot be used for larger strings(lets say, finding the alphabet count from contents of a file).因为,该解决方案不能用于更大的字符串(比方说,从文件的内容中查找字母数)。 You might hit the RunTimeError of Maximum Recursion Depth Exceeded.您可能会遇到超过最大递归深度的 RunTimeError。

Even though you can work around this through setting the recursion depth through setrecursionlimit function, I suggest you to go for other easy ways.尽管您可以通过 setrecursionlimit 函数设置递归深度来解决此问题,但我建议您采用其他简单的方法。 More info on setting the recursionlimithere .有关在此处设置递归限制的更多信息。

Define it outside all function definitions, if you want to use it as a global variable:如果要将其用作全局变量,请在所有函数定义之外定义它:

count = 0
def lenRecur(s): 

or define it as a function attribute:或将其定义为函数属性:

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

This has been fixed in py3.x where you can use the nonlocal statement:这已被固定在py3.x在那里你可以使用nonlocal语句:

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

You don't need count.你不需要数。 The below function should work.下面的功能应该可以工作。


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

Global variable in recursion is very tricky as the depth reaches to its last state and starts to return back to the first recursive call the values of local variables change so we use global variables.递归中的全局变量非常棘手,因为深度达到其最后一个状态并开始返回到第一次递归调用局部变量的值发生变化,因此我们使用全局变量。 the issue with global variables is that when u run the func multiple times the global variable doesn't reset.全局变量的问题在于,当您多次运行 func 时,全局变量不会重置。

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

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