KDC
KDC

Reputation: 1471

Python instance behavior with lists

Consider the following instance behavior in Python.

def change(elements):
    elements[0] = 888
    elements = [-3, -1, -2, -3, -4]
    print(elements[0])

numbers = [1, 4, 5]

print(numbers[0])
change(numbers)
print(numbers[0])
print(numbers)

The Python snippet below prints

1
-3, 
888 
[888,4,5]

Shouldn't it print

1, 
-3, 
-3, 
[-3,-1,-2,-3,-4]

Why would an element in a list by successfully overwritten, but not the entire list object?

Upvotes: 5

Views: 169

Answers (5)

Ravinder Karra
Ravinder Karra

Reputation: 307

Looking at ID's will make understand ...

def change(elements):
    print('inner first elements ID ',id(elements))
    elements[0] = 888
    print('inner second elements ID ',id(elements))
    elements = [-3, -1, -2, -3, -4]
    print('inner third elements ID ',id(elements))
    print('inner third numbers ID ',id(numbers))

numbers = [1, 4, 5]
print(numbers[0])
print('outer numbers ID ',id(numbers))
change(numbers)
print('c ',numbers[0])
print('d', numbers)

Upvotes: 0

scharette
scharette

Reputation: 9987

That is a classic Python variable naming reference confusion. What I really like to to do to understand that though is print a reference to see what is going on.

def change(elements):
    elements[0] = 888
    print("ID of elements is: %d",id(elements))
    elements = [-3, -1, -2, -3, -4]
    print("ID of elements is: %d",id(elements))
    print(elements[0])

numbers = [1, 4, 5]
print("ID of number is: %d",id(numbers))

print(numbers[0])
change(numbers)
print(numbers[0])
print(numbers)

>>>> ('ID of number is: %d', 140036366181584)
1
('ID of elements is: %d', 140036366181584)
('ID of elements is: %d', 140036366181944)
-3
888
[888, 4, 5]

The ID here represents an emplacement in memory. If you run the code the number might be different, but the behavior stays the same.

Basically, when you call

 elements[0] = 888

You're actually mutating numbers (same ID of 140036366181584 in my example).

But, when you call

elements = [-3, -1, -2, -3, -4]

You're creating a new list (different ID of 140036366181944 in my example) and re-assigning the local name elements to it. Yo're simply assigning the name elements to another object. It's not the same list anymore.

So, at this point all you did to numbers is change its first index with the value 888 and this is what the output shows empirically.

Upvotes: 1

Andriy Ivaneyko
Andriy Ivaneyko

Reputation: 22041

No it shouldn't because in first line you override first value of parameter elements and on the second you define new local variable for function.

Upvotes: 0

jdowner
jdowner

Reputation: 736

The list is passed as a reference to the function. So the list is shared between the global space and function. The first change modifies the list and that change is reflected in both spaces. But then you do and assignment to the list variable. That creates a new list in the function. The original list exists in the global space, but it no longer exists in the function. So all of the changes made to the list in the function from that point on are only visible within the function.

Another way of thinking about this instance is that the list is a type of container. The first line of the function changes what is in the container. The second line (the assignment) actually changes the container you are using. This is something that is true for lists but also for any object. This is why the solution given by @Chris_Rands in the comments works: it modifies what is in the container, it doesn't change the container.

Upvotes: 2

Shan
Shan

Reputation: 399

In change function first you use elements from outer scope, that was passed as the argument and is referenced - can be changed within function and those changed will affect the object even out of the local scope.

Then you create local instance of elements, modify it and end the function. Since the elements in global scope were changed earlier, you see "unexpected" result.

Check https://docs.python.org/3/reference/executionmodel.html for more details.

Upvotes: 0

Related Questions