1

First off really sorry for the nondescript title, I don't know how to phrase my question.

Given the code below:

x = [9]
y = [2,4,6]

def f(x, y):
    if len(x) > 0:
        z = x + y
        x.pop(-1)
    return z.pop(0)

print(f(x,y)
print(f(x,y))

The second print line gives me an UnboundLocalError: local variable 'z' referenced before assignment

I understand what this error is, as the function is skipping the if clause and going straight to the return z.pop(0), but z doesn't exist because z is defined in the if clause.

What I would like to know is why the value of x is changed by the function The function skips the if loop because after the first call, x has been changed from x = [9] to x = []

I thought that unless it is a Return statement, then any variables changed or created within a function are local to the function?

For example, geeksforgeeks.org states that

Any variable which is changed or created inside of a function is local, if it hasn’t been declared as a global variable

So why is the value of x changing when it hasn't been returned by the function? Shouldn't the value of x always be [9]?

Thank you

slick
  • 29
  • 1
  • 3
  • You are never creating an `x` in the function (`x=...`) so `x.pop()` mutates the global `x`. – AChampion Sep 15 '17 at 02:19
  • but I am changing x though? Like the quote from geektsforgeeks.org says. So doesn't that mean it stays local? – slick Sep 15 '17 at 02:21
  • The quote is wrong... mutating changes (on mutable types), e.g. `x.pop()` does not create a local `x`. Assignment creates a local variable. – AChampion Sep 15 '17 at 02:23

1 Answers1

1

Lists are mutable. When you pass one into the function then you are really passing in a pointer to the list. It's better to think of Python as pass by reference than pass by value. The x you are changing is not created in the function it is passed in as an argument. You're not changing x (the memory address pointed to by the label x), you're changing the contents of that memory address. See this answer Python functions call by reference

vahndi
  • 1,055
  • 8
  • 16