3

Please look into the code below

def double(arg):
    print("Before: ", arg)
    arg = arg * 2
    print("After: ", arg)

I was studying Head first Python, and I came to this section where they were discussing about pass by value and pass by reference. If we invoke above function with a list as argument such as:

num = [1,2,3]
double(num)
print(num)

The output is :-

Before:  [1, 2, 3]
After:  [1, 2, 3, 1, 2, 3]
[1, 2, 3]

Which seems fine, considering the fact that arg in function double is a new object reference. So the value of num did not change.

But if I use compound operators instead of assignment operators, things work differently as shown:

def double(arg):
    print("Before: ", arg)
    arg *= 2
    print("After: ", arg)

num = [1,2,3]
double(num)
print(num)

The output that I get for this is:

Before:  [1, 2, 3]
After:  [1, 2, 3, 1, 2, 3]
[1, 2, 3, 1, 2, 3]

Why does this happen? I used to think a*=2 and a = a*2 are same. But what's going on in here?

Thanks

saurav
  • 427
  • 4
  • 14

2 Answers2

2

This is a difference between mutable and immutable objects. A mutable object can implement obj *= something by actually modifying the object in place; an immutable object can only return a new object with the updated value (in which case the result is identical to obj = obj * something). The compound assignment statements can handle either case, it's entirely up to the object's implementation.

jasonharper
  • 9,450
  • 2
  • 18
  • 42
2

a *= 2 modifies the structure itself (a) whereas a = a*2 reassigns a as a new variable.

(see this question)

Cary Shindell
  • 1,336
  • 8
  • 25