recursive function return value problems

Discussion in 'Python' started by randomtalk@gmail.com, Dec 28, 2005.

  1. Guest

    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?
    , Dec 28, 2005
    #1
    1. Advertising

  2. 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?
    Brian L. Troutwine, Dec 28, 2005
    #2
    1. Advertising

  3. Dan Sommers Guest

    On 28 Dec 2005 15:25:30 -0800,
    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/>
    Dan Sommers, Dec 29, 2005
    #3
  4. Guest

    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..
    , Dec 29, 2005
    #4
  5. Guest

    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?
    , Dec 29, 2005
    #5
  6. 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.
    Steven D'Aprano, Dec 29, 2005
    #6
  7. Guest

    ah, result = reTest(True) works, thanks alot :D
    , Dec 29, 2005
    #7
  8. 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.
    Steven D'Aprano, Dec 29, 2005
    #8
  9. 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
    =?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=, Dec 29, 2005
    #9
  10. Mike Meyer Guest

    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 <> http://www.mired.org/home/mwm/
    Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
    Mike Meyer, Dec 29, 2005
    #10
  11. Steve Holden Guest

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

    The only thing you appear to have misunderstood is that there;s
    absolutely nothing special about recursive functions at all, and the
    Python interpreter is doing exactly what you told it to.

    regards
    Steve
    --
    Steve Holden +44 150 684 7255 +1 800 494 3119
    Holden Web LLC www.holdenweb.com
    PyCon TX 2006 www.python.org/pycon/
    Steve Holden, Dec 29, 2005
    #11
  12. Guest

    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?

    seems that you want the reTest(True) to be the last and skip the rest.
    If that is the case, put it as "return reTest(True)". Otherwise, the
    last three statements(print, print, return) would happen regardless the
    boolean value.
    , Dec 29, 2005
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Seong-Kook Shin
    Replies:
    1
    Views:
    479
    Richard Bos
    Jun 18, 2004
  2. Greenhorn
    Replies:
    15
    Views:
    794
    Keith Thompson
    Mar 6, 2005
  3. n00m
    Replies:
    12
    Views:
    1,098
  4. vamsi
    Replies:
    21
    Views:
    2,042
    Keith Thompson
    Mar 9, 2009
  5. Replies:
    4
    Views:
    86
Loading...

Share This Page