In fact the y in function and the y in the main function happen to have the same name, but are not the same variable, the are just a reference to the same object. but as soon as you make an assignment to y in the function you crate a new object
In order to make this more clear I renamed y in function() into yy
def function(yy):
yy=yy[:3] # Rewrite the list
return yy
y=[0,1,2,3,4]
y = function(y) # here I assign the result of the function call to y
print(y)
Now A second solution, which might confuse you as it seems to contradict what I said before.
def function(yy):
yy[:]=yy[:3] # Rewrite the list
y=[0,1,2,3,4]
function(y) # here nothing is assigned. function directly modifies the passed object
print(y)
In fact following code in function
y = y[:3]
creates a new list, that contains the first three elements of y and assigns it to a variable, that will be called y, but which is a new object.
The code y[:] = y[:3]
says to keep the same object y, but to replace all of its elements with the first three elements of y.
So again previous code, but now with debug prints:
def function(y):
print("The id of y is ", id(y))
y=y[:3] # Rewrite the list
print("The id of y is ", id(y)) # you created a new object
return y
y=[0,1,2,3,4]
print("The id of y is ", id(y))
y = function(y) # here I assign the result of the function call to y
print(y)
print("The id of y is ", id(y)) # you got a new object, that is no stored in y
And now the other code with debug prints:
def function(y):
print("The id of y is ", id(y))
y[:]=y[:3] # Rewrite the list
print("The id of y is ", id(y))
y=[0,1,2,3,4]
print("The id of y is ", id(y))
function(y) # here nothing is assigned. function directly modified the passed object
print("The id of y is ", id(y))
print(y)