Velocity Reviews > recursive function return value problems

# recursive function return value problems

randomtalk@gmail.com
Guest
Posts: n/a

 12-28-2005
hi, i have the following recursive function (simplified to demonstrate
the problem):

>>> def reTest(bool):

.... result = []
.... if not bool:
.... reTest(True)
.... else:
.... print "YAHHH"
.... result = ["should be the only thing returned"]
.... print "printing result: "
.... print result
.... return result
....
>>> reTest(False)

YAHHH
printing result:
['should be the only thing returned']
printing result:
[]
[]

I don't understand why results are returned twice? is there something
special i missed about recursive functions?

Brian L. Troutwine
Guest
Posts: n/a

 12-28-2005
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
>>>>def reTest(bool):

>
> ... result = []
> ... if not bool:
> ... reTest(True)
> ... else:
> ... print "YAHHH"
> ... result = ["should be the only thing returned"]
> ... print "printing result: "
> ... print result
> ... return result
> ...
>
>>>>reTest(False)

You're both printing the result and returning it. The interpreter just
happens to show both printed and returned variables.

An example of a shown return variable:

>>>def returnb():

.... return 'b'
....
>>>returnb()

'b'

Hope that helps,
Brian

--
What if the Universe were a chrooted environment with everything
symlinked from the host?

Dan Sommers
Guest
Posts: n/a

 12-29-2005
On 28 Dec 2005 15:25:30 -0800,
(E-Mail Removed) wrote:

> hi, i have the following recursive function (simplified to demonstrate
> the problem):

>>>> def reTest(bool):

> ... result = []
> ... if not bool:
> ... reTest(True)

Don't do that. Do this instead:

result = reTest(True)

[ rest of example snipped ]

HTH,
Dan

--
Dan Sommers
<http://www.tombstonezero.net/dan/>

randomtalk@gmail.com
Guest
Posts: n/a

 12-29-2005
the final returned value is: []

the two values printed is (note i only have one print statement
printing "print result",. however, in the actualality, it's printed
twice):
printing result:
['should be the only thing returned']
printing result:
[]

therefore, sadly, i don't thinkg you've understand my problem
correctly..

casevh@comcast.net
Guest
Posts: n/a

 12-29-2005
You have two calls to reTest and so reTest needs to return twice. One
return is from the reTest(True) call back to reTest(False). The second
return is from reTest(False) back to the prompt.

What were you expecting to happen?

Steven D'Aprano
Guest
Posts: n/a

 12-29-2005
On Wed, 28 Dec 2005 15:25:30 -0800, randomtalk wrote:

> hi, i have the following recursive function (simplified to demonstrate
> the problem):
>
>>>> def reTest(bool):

> ... result = []
> ... if not bool:
> ... reTest(True)
> ... else:
> ... print "YAHHH"
> ... result = ["should be the only thing returned"]
> ... print "printing result: "
> ... print result
> ... return result
> ...
>>>> reTest(False)

> YAHHH
> printing result:
> ['should be the only thing returned']
> printing result:
> []
> []
>
> I don't understand why results are returned twice? is there something
> special i missed about recursive functions?

No. What happens when you do this?

py> def test():
.... print "spam"
.... return "Spam"
....
py> test()
spam
'Spam'

I've deliberately spelt one in all lower case, and the other with an upper
case S, so it is easier to see the difference.

When you just call a function from the interactive interpreter without
assigning to a name, Python automatically prints the return value. In your
test above, you call reTest(False) without assigning the result to
anything, so after reTest prints all the various things it has to print,
the interpreter also prints the return result.

If you get that, you can stop reading. Otherwise, here is a more
careful analysis.

When you call reTest(False), it creates a local variable 'result' to the
empty list, then calls reTest(True).

reTest(True) then creates a new local variable 'result', sets it to the
empty list, prints "YAHHH", sets result to a string inside a list. It
prints "printing result", then prints ["should be the only thing..."], and
finally returns that string inside a list.

Control now returns to the *first* call to reTest(False). It accepts that
string inside list, *but throws the result away*. You didn't do anything
with the result! You probably want to change that line to
result=reTest(True).

Because this is inside a function, the result of reTest(True) doesn't get
printed, so you don't see it. (Python only automatically prints results of
things you type at the interactive prompt.)

Execution now continues past the if...else... block. It prints "printing
result", then it prints the value of 'result' which is still equal to the
empty list. Finally it returns the empty list, and the Python interpreter
prints the empty list as a convenience for you.

Calling a recursive function is no different from calling any other
function: you want to assign the result to something.

def factorial(n):
"""Returns n! = 1*2*3*...*(n-1)*n for non-negative int n"""
# this is inefficient code, but it does demonstrate recursion well
if n == 0:
result = 1
else:
result = n*factorial(n-1)
return result

--
Steven.

randomtalk@gmail.com
Guest
Posts: n/a

 12-29-2005
ah, result = reTest(True) works, thanks alot

Steven D'Aprano
Guest
Posts: n/a

 12-29-2005
On Wed, 28 Dec 2005 16:05:30 -0800, randomtalk wrote:

> the final returned value is: []
>
> the two values printed is (note i only have one print statement
> printing "print result",. however, in the actualality, it's printed
> twice):
> printing result:
> ['should be the only thing returned']
> printing result:
> []
>
> therefore, sadly, i don't thinkg you've understand my problem
> correctly..

I wonder what you think your problem is.

You make TWO calls to reTest (the first one you explicitly call, then the
recursive call). 'print "printing result:"' happens in *every* call to
reTest, regardless of the argument, so of course it gets printed twice.
What did you expect to happen?

By the way, it is Bad with a capital B to shadow the names of built-in
functions as you do:

def reTest(bool): # don't use bool as the name of an argument!

bool is a built-in type. By using that name as an argument, you now
have made the built-in type inaccessible to your code, which is a potent
source of hard-to-track-down bugs.

--
Steven.

=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=
Guest
Posts: n/a

 12-29-2005
(E-Mail Removed) wrote:
> ... if not bool:
> ... reTest(True)

> I don't understand why results are returned twice? is there something
> special i missed about recursive functions?

Yes, although it is not clear *what* it is that you are missing.

Here is my guess: you fail to see that reTest *continues* after
the recursive call returns. So you get this

reTest(False)
result = []
reTest(True)
result = []
print "YAHH"
result = ["should be the only thing returned"]
print "printing result: "
print ["should be the only thing returned"]
return ["should be the only thing returned"]
# result value discarded by caller
print "printing result: "
print []
return []
# interactive shell prints result value: []

If you agree that this is what happens, please explain what it is
that you were missing.

Alternative guesses what it is that you are missing:
- there is one result variable per reTest call, as result is
not global
- you forgot to assign the result of the recursive call
- you missed the fact that the interactive shell also prints
the final result.

Possible corrections:
1. you only want a single print statement executed. Write
.... if not bool:
.... return reTest(True)
2. you never want the empty list printed. Write
.... if not bool:
.... result = reTest(True)
3. you don't want the interactive shell to print the value.
Write
>>> res = reTest(False)

HTH,
Martin

Mike Meyer
Guest
Posts: n/a

 12-29-2005
(E-Mail Removed) writes:
> hi, i have the following recursive function (simplified to demonstrate
> the problem):
>>>> def reTest(bool):

> ... result = []
> ... if not bool:
> ... reTest(True)
> ... else:
> ... print "YAHHH"
> ... result = ["should be the only thing returned"]
> ... print "printing result: "
> ... print result
> ... return result
> ...
>>>> reTest(False)

> YAHHH
> printing result:
> ['should be the only thing returned']
> printing result:
> []
> []
>
> I don't understand why results are returned twice? is there something
> special i missed about recursive functions?

Depends on what you're complaining about. If it's the two []'s at the
end, one is printed by "print result", and the other is printed by the
interactive interpreter as the return value of retest.

If, on the other hand, it's that you get "printing result:" twice,
with two different values, it's because you called reTest twice: once
from the interactive interpreters prompt (bool = False in this case)
which returns [], and once recursively (bool = True in this case)
which returns ["should be the only thing returned"]. If the latter,
there's something you are missing about recursive functions.

<mike
--
Mike Meyer <(E-Mail Removed)> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.