1

I am new to Python and I am trying to understand when we can modify a variable used in a function.
In the example below, the object bound to x is not modified by f as we can see in the output. I don't understand why. From my understanding, when we do x.append(4) in f, we modify the object bound to the name x. But it seems that it is not the case, given the output. Where is my error?:

Am i missing something with global variables vs local variables?

Is there a copy of the object which is done when we call f?

My question is similar to this question. However the conclusion was not clear for me and it didn't help me to understand where I was wrong.

def f(x):
    x = [0,1,2,3]
    x.append(4)
    print('In f():', x)

x = [0,1,2,3]
print('Before:', x)
f(x)
print('After :', x)

Output

Before: [0, 1, 2, 3]
In f(): [0, 1, 2, 3, 4]
After : [0, 1, 2, 3]
Sara Mun
  • 73
  • 7
  • 3
    `x = [0,1,2,3]` - you do that **inside the function** too. Delete that line and you'll see the argument value *does* get modified if you don't immediately shadow it with a new object. *"we modify the object bound to the name `x`"* - yes, but you've explicitly bound a different object. – jonrsharpe Oct 09 '17 at 11:11
  • 1
    You are not modifying the `x` from the global namespace but the newly created one in the functions namespace. They are different objects even that they have the same name (in different namespaces). – Klaus D. Oct 09 '17 at 11:14
  • https://nedbatchelder.com/text/names.html – chepner Oct 09 '17 at 11:16
  • why would your function take x, then to just to redefine it? – CodeCupboard Oct 09 '17 at 11:27
  • Thank you jonsharpe and Klaus – Sara Mun Oct 09 '17 at 11:51

3 Answers3

2

When you do this statement:

x = [0,1,2,3] 

Inside the body of f, it creates a brand new x just for that f.

You can check this yourself by printing the id of the variable:

>>> def f(x):
...    x = [0,1,2,3]
...    x.append(4)
...    print('Inside f, x is: {} with id: {}'.format(x, id(x)))
...
>>> x = [0,1,2,3]
>>> print('{} {}'.format(x, id(x)))
[0, 1, 2, 3] 139706697083592
>>> f(x)
Inside f, x is: [0, 1, 2, 3, 4] with id: 139706697093064

Now, to use the x from outside of f, just get rid of the assignment operation:

>>> def f2(x):
...     x.append(4)
...     print('Inside f2, x is: {} with id: {}'.format(x, id(x)))
...
>>> print('{} {}'.format(x, id(x)))
[0, 1, 2, 3] 139706697083592
>>> f2(x)
Inside f2, x is: [0, 1, 2, 3, 4] with id: 139706697083592
>>> x
[0, 1, 2, 3, 4]

You'll not that the id is the same, and more importantly, the value of x outside the function has also changed.

Burhan Khalid
  • 169,990
  • 18
  • 245
  • 284
0

If you want to change the value of x try this:

def f(x):
    x.append(4)
    print('In f():', x)

x = [0,1,2,3]
print('Before:', x)
f(x)
print('After :', x)

By doing so you will pass x to the function and edit it.

primef
  • 199
  • 10
0

You are redeclaring x in your function. The x inside your function is not the same x outside your function. Furthermore, you cannot call the x from inside your function. So in order to make your code work, you need to delete the x from inside your function.For more information go see Python variable scope

Lame Fanello
  • 545
  • 1
  • 6
  • 15