Your code reads:
def func(first):
third = first[0]
first[0][0] = 5
print(third)
first = [[3,4]]
func(first)
What's happening is this:
- In
func()
, the argument first
contains a reference to a list of lists with value [[3,4]]
.
- After the assignment to
third
, third
contains a reference to the list [3,4]
at position 0 in the list referenced by first
. No new list object has been created and no copy of a list has taken place, rather a new reference to the existing list has been created and stored in the variable third
.
- In the line
first[0][0] = 5
, the item at position 0 in the list [3,4]
is updated so that the list is now [5,4]
. Note that the list [3,4]
that was modified is an element of the list of lists referenced by first
, and it is also the one referenced by third
. Because the object (namely, the list) that is referenced by third
has now been modified, any use of this reference to access the list (such as print(third)
) will reflect its updated value, which is [5,4]
.
UPDATE:
The code for your updated question is:
def func(first):
third = first[0][0:2]
first[0][0] = 5
print(third)
first = [[3,4]]
func(first)
In this case, the assignment third = first[0][0:2]
takes a slice of the list [3,4]
at position 0 in the list of lists referenced by first
. Taking a slice in this way creates a new object which is a copy of the subsequence indicated by the arguments specified in the square brackets, so after the assignment, the variable third
contains a reference to a newly created list with value [3,4]
. The subsequent assignment first[0][0] = 5
updates the value of the list [3,4]
in position 0 of the list of lists referenced by first
, with the result that the value of the list becomes [5,4]
, and has no effect on the value of third
which is an independent object with value [3,4]
.
Importantly (and potentially confusingly), slice notation used on the left-hand side of an assignment works very differently. For example, first[0][0:2] = [5,4]
would change the contents of the list first[0]
such that the elements in index 0 and 1 are replaced by [5,4]
(which in this case means the value of the list object would be changed from [3,4]
to [5,4]
, but it would be the same object).