2

I'd like to clarify a simple pointer mechanic in Python. Consider the following:

u = [1,2]
v = [u,3]
print(v)
u[0] = 100
print(v)

Then the result is

[[1,2],3]
[[100,2],3]

Meanwhile if we perform

u = [1,2]
v = [u,3]
print(v)
u = [100,2]
print(v)

Then the result is

[[1,2],3]
[[1,2],3]

I think this happens because in the first code, the pointer that u stores doesn't change throughout while in the second code, the pointer that u stores changed from the declaration u=[100,2] but the declaration v=[u,3] stored the initial pointer itself and not the variable u.

Is this the correct explanation as to why this happened?

finnlim
  • 130
  • 6
  • 2
    Definitely. To get the same behaviour for the second array you would have to do u[:] = [100, 2]. – SdahlSean Dec 28 '19 at 18:25
  • 6
    Mandatory link to Ned Batchelder’s article: https://nedbatchelder.com/text/names.html – quamrana Dec 28 '19 at 18:34
  • 2
    The assignment in the second example makes `u` *point to* a different object, so operations on/to `u` no longer affect the object in `v`. - https://nedbatchelder.com/text/names.html. … https://docs.python.org/3/reference/executionmodel.html#naming-and-binding … https://docs.python.org/3/reference/simple_stmts.html#assignment-statements. – wwii Dec 28 '19 at 18:34
  • If you run both of your examples in Python Visualizer tool you will easily be able understand what's happening http://www.pythontutor.com/visualize.html#mode=edit – Bikramjeet Singh Dec 28 '19 at 18:37
  • 1
    Python containers hold references to objects. Everything is an object. A value is an object. A name is a reference (and either term is preferable to the term variable, which recalls a box storing a value, as this does not apply to Python). You bind names to objects, or change objects in place. Re binding a name to another object does not affect the original object unless there are no more references to it. – progmatico Dec 28 '19 at 18:38
  • When you change an object pointed by several references, the changes can be seen through all the references. – progmatico Dec 28 '19 at 18:40
  • It's very important to understand that **Python does not have pointers** – juanpa.arrivillaga Dec 28 '19 at 19:09

1 Answers1

3

Python has no concept of pointers and thinking about Python constructs in terms of pointers can be misleading. Python has names and references to objects instead of pointers (everything is an object in Python).

The assignment operator (=) is used to bind a name to an object with a reference. When you access the object with its name, you get the object instead of the reference. You can't access the value of the reference and there is no way to manipulate references similar to pointer arithmetic in C. With this in mind, let me break down your code in Python terms:

# A new list object is created and bound to the name `u`. 
# It only has `int` elements which are immutable
u = [1,2]
# A different list object is created and bound to the name `v`.
# Its first element is an other list object which is bound to the name `u` at this point. 
v = [u,3]
print(v)
# __setitem__(0, 100) is called on the list object under the name `u`
# The first element of `v` remains this altered object.
u[0] = 100
print(v)

# Same as before
u = [1,2]
v = [u,3]
print(v)
# A new list object is created and bound to the name `u`.
# The previous list object bound to `u` remains the first element of `v` which is unchanged.
u = [100,2]
print(v)

Hope this helps

Agost Biro
  • 2,709
  • 1
  • 20
  • 33