tags:

views:

45

answers:

1

I have a problem with python here. If I pass an array through a recursive function that adds something to the array each time it is called, the array is modified in each instance

Code:

def test(n,myList):
    if n>0:
        myList.append("Test")
        print ( "BEFORE CALL Instance ", n, myList )
        test(n-1,myList)
        print ( "AFTER CALL Instance ", n, myList )
    else:
        return

Execution via test(5,[])

Results:

BEFORE CALL Instance  5 ['Test']
BEFORE CALL Instance  4 ['Test', 'Test']
BEFORE CALL Instance  3 ['Test', 'Test', 'Test']
BEFORE CALL Instance  2 ['Test', 'Test', 'Test', 'Test']
BEFORE CALL Instance  1 ['Test', 'Test', 'Test', 'Test', 'Test']
AFTER CALL Instance  1 ['Test', 'Test', 'Test', 'Test', 'Test']
AFTER CALL Instance  2 ['Test', 'Test', 'Test', 'Test', 'Test']
AFTER CALL Instance  3 ['Test', 'Test', 'Test', 'Test', 'Test']
AFTER CALL Instance  4 ['Test', 'Test', 'Test', 'Test', 'Test']
AFTER CALL Instance  5 ['Test', 'Test', 'Test', 'Test', 'Test']

Actual problem:

Each child function is modifying the array in all parent functions. How can I prevent this?

Copying the list into a new one and modifying it results in the same output as above

myListNew=myList
myListNew.append("Test")
+5  A: 

Your attempted solution does not actually copy the array. It assigns a new name to the same array. If you want to create a new array, try this:

my_new_list = my_list[:]

That creates a list containing a slice of the old list, where the slice starts at the beginning, and ends at the end. In other words, a perfect copy of the list.

jcdyer
+1 - Exactly, just change to `test(n-1,myList[:])`
sberry2A
Is there some workaround on doing this on arrays (dictionaries) too? it says "unhashable type".
lamas
Check out the copy module in the library: `another_d = copy.copy(d)`. Or try `another_d = dict(d)`.
jcdyer
@sberry2A That works perfectly. My preference would be to do it *inside* test, to follow the general principle of not changing the data your caller provides. Then you don't have to worry about copying whenever you call `test()`. IOW, let them call `test(n-1, myList)`, and then do `newlist = mylist[:]` right away inside, and do all work on `newlist`.
jcdyer