dansalmo
dansalmo

Reputation: 11696

Python list corrupted by method that returns a list

I am new to python and have been unable to find anything that explains the behavior I am seeing below. I noticed the problem when returning a list from a method and distilled it down to the simplest form that shows the problem. I figured out a workaround but would like to know what I am missing in my understanding since I would expect both examples to behave the same.

class MyCount:
    """A simple count test to show return list problem"""
    def __init__(self):
        self.next = [0]

    def count_good(self):
        self.next[0] += 1
        return [self.next[0]]

    def count_bad(self):
        self.next[0] += 1
        return self.next # returning using this form corrupts the recieving list


c=MyCount()
result=4*[0]
result[0]=c.count_good()
result[1]=c.count_good()
result[2]=c.count_bad()
print result
result[3]=c.count_bad()
print result


>>> c=MyCount()
>>> result=4*[0]
>>> result[0]=c.count_good()
>>> result[1]=c.count_good()
>>> result[2]=c.count_bad()
>>> print result
[[1], [2], [3], 0]
>>> result[3]=c.count_bad()
>>> print result
[[1], [2], [4], [4]]   <--- the return changed the previous item in the list
>>>
>>> c=MyCount()
>>> result=4*[0]
>>> c.count_good()
[1]
>>> c.count_good()
[2]
>>> c.count_bad()
[3]
>>> c.count_bad()  <--- seems to work fine when not returning to a list
[4]
>>> 

Upvotes: 0

Views: 358

Answers (1)

Amber
Amber

Reputation: 527063

When you return self.next, you're returning a reference to the actual list object which self.next refers to, not a copy. Thus, any changes made to that original list object from anywhere will be reflected in all of the places which reference that original object.

In order to return a copy, you should either make a full slice:

return self.next[:]

or use the list() function:

return list(self.next)

Upvotes: 4

Related Questions