Recursion and Variable Scope

Michael Abbott michael at rcp.co.uk
Fri Sep 7 03:43:26 EDT 2001


mudpyr8 at yahoo.com (mudpyr8) wrote in 
news:d9f7d05e.0109061911.6bdcda3f at posting.google.com:

> I'm writing a simple function. It is recursive. Here's the code:
> 
> ##########################
> def generate(sides, dice, roll):
>      if dice > 0:
>           for x in range(sides):
>                roll.append(x+1)
>                generate(sides, dice - 1, roll)
>                roll.pop()
>      else:
>           print roll
> ##########################
> 
> When calling it: generate(4, 2, [])
> will generate output of 16 pairs of values, 1-4 each. However, I
> cannot get that result stored in an object; I can only print it.
> 
> The last line is the tricky part. Where it says   # print roll #   I
> want it to do something like:   # rolls.append(roll) #  .
> Unfortunately, creating a variable   # rolls = [] #   outside of the
> function definition, and even stating   # global rolls #   on the
> first line of the block doesn't seem to matter.
> 
> I've tried to wrap my mind around this but am stuck. I need to perform
> further manipulation on the results, but have no object with which to
> do so. I know I could write to a file (maybe, if the file handle works
> within the recursion) and then read it but that seems like a waste of
> time.
> 
> I hope I'm just missing something obvious. Please, any help would be
> appreciated.
> 

It would have helped if you'd been a bit more explicit about the problem 
you're seeing, but one answer is quite straightforward.

If you replace "print roll" with

    	global rolls
    	rolls.append(roll)

then the result you get is a list of empty lists, not quite what you had in 
mind, and at first somewhat unexpected.
    	The problem is that when you append roll to the accummulating result 
list, it is still mutable, and you carry on working with roll in subsequent 
processing.  You need, therefore, to put a *copy* of roll on the list.  The 
following works:

    	global rolls
    	rolls.append(roll[:])

However, using a global like this isn't a good idea.  You should look 
instead to get generate() to return the list you're after.  Also note that 
this problem is nothing to do with variable scope: it is simply a 
consequence of the fact that roll is the same (mutable) list throughout.



More information about the Python-list mailing list