2013-06-27 4 views
7

ОК, я использую Python 2.7.3 и вот мой код:Глобальные переменные в рекурсии. Python

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. Если я ставлю переменный счетчик вне функции lenRecur он прекрасно работает в первый раз, но если я пытаюсь снова без перезагрузки оболочки Python, граф (очевидно) Безразлично» t, поэтому он продолжает добавлять.
  2. Если я меняю линию count += 1 на count = 1, она также работает, но выход (очевидно) один.

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

Заранее благодарен!

+0

не может видеть рекурсию. – oleg

+0

Извините, сейчас все в порядке! –

ответ

12

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

Вам нужно будет использовать Python 3, прежде чем вы сможете сделать эту работу таким образом; Вы ищете nonlocal statement добавлен в 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 
+0

Есть ли способ сделать это в Python 2.7? –

+0

или Вы можете передать счет как параметр функции 'leng' – oleg

+0

Хорошо, что сработало для меня! Могу ли я спросить, почему список работал, а не нормальная переменная? –

0

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

count = 0 
def lenRecur(s): 

или определить его как атрибут функции:

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

Это было исправлено в py3.х, где вы можете использовать nonlocal заявление:

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

Если я определяю его вне функции, то lenRecur - это первое утверждение, которое я сказал, что я пытался. Спасибо, в любом случае! –

+0

@CarlesMitjans Я догадываюсь, что пропустил эту деталь, вы можете определить ее как атрибут функции. –

+0

Не волнуйся :) спасибо за ответ! –

0

Вам не нужно количество. Функция ниже должна работать.

 

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

Также работал! Благодаря!! –

4

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

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) или сама обезьяна-латания функции пример.

+0

Ой! Не думал об этом. Благодаря! –

+0

Я отправил тот же ответ. Не видел ваш пост там. Наверное, я опаздываю, как обычно :-) – thiruvenkadam

+2

Лучше проголосовать за мое решение, а не прокомментировать его;) – oleg

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, я предлагаю вам пойти другими путями. Дополнительная информация о настройке рекурсивного ограничения here.