Global variables in recursion. python

OK, I am using Python 2.7.3 and here is my code:

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 am trying to change the count variable inside the leng function. Here is what I tried:

  • If I put the variable count outside the lenRecur function, it works great the first time, but if I try again without restarting the python shell, the counter (obviously) will not restart, so it will continue to add.
  • If I change the line count += 1 to count = 1 , it also works, but the output is (obviously) one.

So, my goal is to get the length of the string using recursion, but I don't know how to track the number of letters. I was looking for information about global variables, but I'm still stuck. I don't know if I understood this yet, or if I have a problem in my code.

Thanks in advance!

+7
source share
5 answers

count in lenRecur not global. This is a variable with scope.

You will need to use Python 3 before you can do this work this way; you're looking for a nonlocal instruction added in Python 3.

In Python 2, you can get around this limitation by using a variable (like a list) for count instead:

 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 no longer change the name count ; it remains unchanged, it refers to the same list. All you do is change the first element in the count list.

An alternative β€œspelling” would be to make the count attribute of the function:

 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 no longer local to lenRecur() ; it became an attribute for the immutable lenRecur() function.

For your specific problem, you are actually thinking too much. Just recursion summarizes:

 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 
+12
source

I think you can pass the score as the second argument

 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 drowning out objects from the outside, for example using mutable objects ( list or dict ) or the monkey interception function itself.

+4
source

You need to make the count variable a function variable, like

 def lenRecur(s): lenRecur.count = 0 

However, I see some problems with the code.

1) If you try to find the number of alphabets in a string through recursion, this will do:

 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 to have one function to complete the task, for example, there will be no leng method at all.

2) If your goal is just to find the number of alphabets in a string, I would prefer a list comprehension

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

If this is something other than the purpose of the training, I suggest you avoid recursion. Because the solution cannot be used for large strings (say, finding the number of alphabets from the contents of a file). You can hit the height of a RunTimeError with the maximum recursion depth.

Despite the fact that you can get around this by setting the recursion depth through the setrecursionlimit function, I suggest you go the other way. Read more about setting recursionlimit here .

+1
source

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 an attribute of a function:

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

This has been fixed in py3.x, where you can use the nonlocal operator:

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

You do not need to count. The function below should work.

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

All Articles