Глобальные переменные в рекурсии. Питон

хорошо, я использую 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 внутри

5 ответов


count на lenRecur is не глобальная. Это переменная с областью видимости.

вы должны использовать Python 3, прежде чем вы можете сделать эту работу таким образом, вы ищете nonlocal сообщении добавлено в Python 3.

в 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

Я думаю, вы можете передать счет как второй аргумент

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

    return leng(isChar(s), 0)

это должно работать лучше, чем приглушение объектов из внешней области, таких как использование изменяемых объектов (list или dict) или сама функция исправления обезьян, например.


вам нужно сделать переменную count переменной функции, такой как

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)

но все же я предпочел бы иметь одну функцию для выполнения задачи, как будто не будет никакого метода Ленга вообще.

2) Если ваша цель просто найти количество букв в строке, я бы предпочел список понимания

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

Если это что-то иное, чем цель обучения, я предлагаю вам избегать рекурсии. Потому что решение не может быть использовано для больших строк (скажем, найти количество алфавитов из содержимого файла). Вы можете нажать RunTimeError максимальной глубины рекурсии превышен.

хотя вы можете обойти это путем установки глубины рекурсии через функцию setrecursionlimit, я предлагаю вам пойти другими простыми способами. Подробнее о установка recursionlimit здесь.


определите его вне всех определений функций, если вы хотите использовать его как глобальную переменную:

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