Reputation: 19
A python script like the following. The list 'a' cannot be updated correctly:
def test(b, a):
print(a)
a.append(10)
a = b
print(a)
a = [1, 2, 3]
b = [4, 5, 6]
test(b, a)
print(a)
The results were printed out like below. The list 'a' was changed as [1, 2, 3, 10] NOT [4, 5, 6]. Why?
Upvotes: 1
Views: 580
Reputation: 1008
This is a scope issue. Within test
the variable a
, b
are local references to objects a
and b
outside of test. Thus a
and b
in the context of test
can be named anything.
Here's the code with some printouts that'll help explain this better:
def test(test_b, test_a):
print('test_a references object in memory {} with values {}'.format(id(test_a), test_a))
print('append(10)')
test_a.append(10)
print('test_a references object in memory {} with values {}'.format(id(test_a), test_a))
print('assign reference test_a = test_b # new value {}'.format(id(test_b)))
test_a = test_b
print('test_a references object in memory {} with values {}'.format(id(test_a), test_a))
outside_a = [1, 2, 3]
outside_b = [4, 5, 6]
test(outside_b, outside_a)
print('outside_a references object in memory {} with values {}'.format(id(outside_a), outside_a))
A sample output of this would be like:
test_a references object in memory 140058884752448 with values [1, 2, 3]
append(10)
test_a references object in memory 140058884752448 with values [1, 2, 3, 10]
assign reference test_a = test_b # new value 140058887943936
test_a references object in memory 140058887943936 with values [4, 5, 6]
outside_a references object in memory 140058884752448 with values [1, 2, 3, 10]
Upvotes: 0
Reputation: 146
This is because by sending the variables a
and b
to the function, you created copies of them.
They point to the same data and you can modify it but when you assign a completely different list to the variable in the function, the original variable outside the function stays unchanged.
I would recommend returning the new lists from the function if you want to change the original variables. Like this:
def test(b, a):
print(a)
a.append(10)
a = b
print(a)
return b, a
a = [1, 2, 3]
b = [4, 5, 6]
b, a = test(b, a)
print(a)
Upvotes: 0
Reputation: 377
You need to use a return
statement to update a
. Set a
equal to the return value of the function.
def test(b, a):
print(a)
a.append(10)
a = b
return a
a = [1, 2, 3]
b = [4, 5, 6]
a = test(b, a)
print(a)
Upvotes: 1
Reputation: 113948
you simply created a new local variable a
that was equal to b
, that shadowed the a
you passed in
you can do inplace replacement with slice notation
a[:] = b
would replace the value of a that you passed in
Upvotes: 1