I have a list called ones that changes value after a block of code that shouldn't affect it. Why?
s = 3
ones = []
terms = []
for i in range (0, s):
ones.append(1)
terms.append(ones)
print(terms)
twos = []
if len(ones) > 1:
twos.append(ones)
twos[-1].pop()
twos[-1][-1] = 2
print(twos)
print(terms)
Output:
[[1, 1, 1]] # terms
[[1, 1, 2]] # twos
[1, 1, 2] # terms
For context, I'm trying to use this to begin to solve the problem on page 5 of this British Informatics Olympiad past exam: http://www.olympiad.org.uk/papers/2009/bio/bio09-exam.pdf.
Here:
twos.append(ones)
You are appending a reference to ones, not its values. See the difference:
In [1]: l1 = [1, 2, 3]
In [2]: l2 = []
In [3]: l2.append(l1)
In [4]: l2, l1
Out[4]: ([[1, 2, 3]], [1, 2, 3])
In [5]: l2[0][1] = 'test'
In [6]: l2, l1
Out[6]: ([[1, 'test', 3]], [1, 'test', 3])
In order to avoid this you can give a copy by using [:] operator:
In [7]: l1 = [1, 2, 3]
In [8]: l2 = []
In [9]: l2.append(l1[:])
In [10]: l2, l1
Out[10]: ([[1, 2, 3]], [1, 2, 3])
In [11]: l2[0][1] = 'test'
In [12]: l2, l1
Out[12]: ([[1, 'test', 3]], [1, 2, 3])
twos.append(ones) does not copy ones.
There is only ever one list ones in memory, which also goes by the following references:
terms[0]twos[0]and also terms[-1] and twos[-1] because terms and twos only have one element each, so the first is the last.
Now, when you mutate ones/terms[0]/terms[-1]/twos[0]/twos[-1] you are mutating the same list in memory.
I highly recommend watching Facts and Myths about Python names and values.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With