There is no âoriginal listâ and âchanged listâ. There is one list, which you identify as b and then append to a three times. Itâs always the same list, no matter what you do with it. So when you change whatâs in b[0], youâre changing that list, that one single list that you see three times in the output.
Appending doesnât make a copy of the list, it uses the same list object. So if you append b three times, and then print, you will see b three times.
Another way of looking at this is that you now have a single list object with four names: b, a[0], a[1] and a[2]. Not four lists, there is only one list but with four different ways to refer to it.
Thatâs like there are many different ways people can refer to me:
Steve
Steven
âMr DâŚâ
stevend@some_email_address
âHey you over there!â
but if Steve gets a tattoo so does Mr D because theyâre the same person.
If you want to take a snapshot of b so that it becomes independent of future changes, you need to make a copy. You can copy the list (at least) four ways:
a = []
b = ['initial value']
a.append(b) # Uses the actual b list.
a.append(b.copy()) # Make a copy.
a.append(b[:]) # Use slicing to make a copy.
import copy
a.append(copy.copy(b)) # Use the copy module.
a.append(copy.deepcopy(b)) # Make copies of the contents of b as well as b.
Slicing is probably the fastest.
Now the a list contains:
The b list itself; changes to b will be visible in a[0].
The .copy method is returning a âshallowâ copy; itâs copying the list, but not itâs not copying each element of the list.
For a âdeepâ copy, use the deepcopy function of the copy module:
from copy import deepcopy
# Other lines...
variants.append(deepcopy(original_list))
Incidentally, itâs better to post text, properly formatted, rather than a picture. Some people rely on screen readers, and itâs not fun having to re-type code from a picture.