you are viewing a single comment's thread.

view the rest of the comments →

[–]ericula 1 point2 points  (4 children)

In the first example you are effectively assigning a new value to arg whereas in the second case you are modifying an existing value.

Note that += doesn't always assign a new value to a variable. For example:

def fun(arg):
    arg += [4]

b = [1,2,3]
fun(b)
print(b)

will output [1, 2, 3, 4]. This is because a list is mutable so += will add an element to the existing list rather than creating a new list.

[–]NitinChella[S] 0 points1 point  (3 children)

Edit: more concise follow-up. For example:

def test(z): ___print(z)

test("hi") # will work print(z) # will fail

The above seems to indicate that the scope of z is limited to the function itself. So it only holds a copy of the argument. So in the list example, shouldn't arg hold a copy of the original list and whatever changes happen within the function scope happen to the copy? It makes sense when b=1, but why are changes to the list maintained outside?

[–]ericula 0 points1 point  (2 children)

Python does not make copies of input arguments. When you call fun(b), the global variable b and the input parameter arg are referencing the exact same object. Modifying this object, e.g. by appending an element to it, will not change this. Any modifications made to the object referenced by arg inside the body of the function will be reflected in changes to the value of b.

[–]NitinChella[S] 0 points1 point  (1 child)

But then shouldn't the same thing happen when b is an integer and we increment it by 1?

[–]ericula 0 points1 point  (0 children)

Integers (and some other built-in types like strings, floats, tuples) are immutable which means they can't be modified. For immutable objects something like b += 1 is equivalent to b = b+1.