I have just started python and came across something kind of strange.
The following code assigns a co-ordinate of x=1 and y=2 to the variable test. The test2 variable assigns itself the same value as test and then the [x] value for test2 is changed to the old [x] value minus 1. This works fine, however, when the last part is executed, not only does it minus 1 from the [x] value in test2, it does the same to the [x] value in the test variable too.
test = [1,2];
test2 = test;
test2[1] = test2[1] - 1;
I found doing the following worked fine but I still don’t understand why the first method changes the test value as well as the test2 value.
test = [1,2];
test2 = test;
test2 = [test2[0] -1 ,test2[1]];
Could someone please explain why this happens.
Thank You
TheLorax
In Python, like in Java, assignment per se never makes a copy — rahter, assignment adds another reference to the same object as the right-hand side of the
=. (Argument passing works the same way). Strange that you’ve never heard of the concept, when Python is quite popular and Java even much more so (and many other languages tend to work similarly, possibly with more complications or distinguos).When you want a copy, you ask for a copy (as part of the expression that is on the right-hand side, or gets used to get the argument you’re passing)! In Python, depending on your exact purposes, there are several ways — the
copymodule of the standard library being a popular ones (with functionscopy, for “shallow” copies, anddeepcopy— for “deep” copies, of course, i.e., ones where, not just the container, but every contained item, also gets deep copied recursively).Often, though, what you want is “a new list” — whether the original sequence is a list, a copy, or something else that’s iterable, you may not care: you want a new
listinstance, whose items are the same as those of “something else”. The perfect way to express this is to uselist(somethingelse)— call thelisttype, which always makes a new instance of list, and give it as an argument the iterable whose items you want in the new list. Similarly,dict(somemapping)makes a newdict, andset(someiterable)makes a new set — calling a type to make a new instance of that type is a very general and useful concept!