3

I'm confused with the pass-by-ref and pass-by-value in Python. In the following code, when listB = listA, listB should being assigned the pointer (reference) to the list in ListA variable. Any changes to listB should be reflected on listA. However, that is not the case in my test. Am I doing something wrong with the code? I'm running Python 3.4.3

>>> listA = [1,2,3]
>>> listB = listA
>>> listA = [4,5,6]
>>> print(listA, listB)
[4, 5, 6] [1, 2, 3]
>>> listB[0] ='new'
>>> print(listA, listB)
[4, 5, 6] ['new', 2, 3]
1
  • 3
    you are re-assigning listA, so it is no longer pointing at the same value as listB Commented Oct 31, 2015 at 4:08

4 Answers 4

2

You're reassigning listA altogether, so there is no relation between it and listB.

For example:

listA = [2,2,3]

listB = listA

id(listA)
Out[6]: 90404936

id(listB)
Out[7]: 90404936

listA[0]=2

id(listA)
Out[9]: 90404936

listB
Out[10]: [2, 2, 3]

But then when you reassign listA you lose that id:

listA = [3,3,3]

id(listA)
Out[12]: 92762056

But listB stays at the same id:

id(listB)
Out[13]: 90404936
Sign up to request clarification or add additional context in comments.

Comments

1

When you do listA = [4,5,6], the reference to listA (that was assigned to listB) no longer points to listA, since you completely replaced listA with a new list.

If you remove that line, you will find that it works as expected.

Comments

1

You say:

I'm confused with the pass-by-ref and pass-by-value in python.

Actually Python does not use either call-by-value or call-by-reference: it uses call-by-object-sharing. This is basically like call-by-value, except that the "value" in question is actually the reference to the object that holds the actual value.

Fundamentally, the way to think about variables in Python is that they are actually names that can refer to other objects, not values themselves.

Comments

0

For Python, think of a namespace as being implemented by a 2-column table listing names and addresses. Also, note that the assignment operator = causes the right side to be evaluated, represented in memory if not already represented, and then causes the variable on the left side of the assignment to be bound in the symbol table to the address of the representation. Working through your code one line at a time:

listA = [2, 3, 4]

causes 2, 3, and 4 to be represented in memory at particular addresses. Then the brackets cause a list object to be represented in memory, with an address for the class, an int for its length, and an array of addresses for its elements. Finally, the name listA is placed in the namespace table and bound to the address for that list object.

listB = listA

A second entry listB is made in the namespace table and bound to the same address for the list.

listA = [4, 5, 6]

creates representations of three ints and a list in memory and changes the address referenced by listA in the namespace table, binding it to the new list.

listB[0] = 'new'

causes the string 'new' to be represented in memory and then changes the list object bound to listB so that that list's first element now refers to the address of the string.

If listA hadn't been reassigned to a new object, it would still point to the same list and you would see the same change in the list's first element whether using the listA or listB token.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.