-5

I was trying to find a solution to mutate a list by passing it to the function as an argument. For example:

def f(x):
    x = x*2
x = [9,8,7]
f(x)
print(x)

I want the result to be:

[9, 8, 7, 9, 8, 7]

but it ended up like this:

[9, 8, 7]

and then I stumbled with this thread: https://stackoverflow.com/a/31359713/13275449

The solution works wonderfully

def f(x):
    x[:] = x*2
x = [9,8,7]
f(x)
print(x)

[9, 8, 7, 9, 8, 7]

My question is why we need the [:] ? I thought its the other way around, If we dont want to mutate the original list, we put [:] after it to copy it. But this one seems to be the opposite. It probably has something to do with global and function scope. I tried to use the pythontutor but still confused.

Thank you!

EDIT: semicolon -> colon

wanburana
  • 157
  • 1
  • 9
  • 6
    That is not a semicolon. – khelwood Jul 04 '20 at 09:13
  • Did you forget to return it from the function? Note that in the first case you're just reassigning the variable x to something else (x * 2 creates a new list). – cs95 Jul 04 '20 at 09:13

2 Answers2

0

As the other answers say: this behavior is caused by function scope and global scope. Just to be clear, let's call local x to x inside the function and global x the other one. You pass global x value as parameter to f function, then using its values you're creating a new variable local x, the second one is not relating to the first one because it just exits inside the function and you won't be able to call it outside of it, you won't facing this confusion if you rename the local x as y as follow:

def f(x):
    y = x*2
    print(f'Inside function: {y}')
x = [9,8,7]
f(x)
print(f'Global x: {x}')

Output:

Inside function: [9, 8, 7, 9, 8, 7]
Global x: [9, 8, 7]

The other hand, with x[:] you actually point to global x and that's the reason why you can print its value otherwise using y instead of local x you'll get an error as below:

Traceback (most recent call last):
File [file_name], line 6, in <module>
print(f'Global x: {y}')
NameError: name 'y' is not defined
Brad Figueroa
  • 869
  • 6
  • 15
-1

Well this is concept of shallow copy and deep copy passing a list[:] like this will create a shallow copy of the list and assign all the references of original list to the new copy created. Refer the docs for more details i have added a link to it. Let me know if this helps brother!!!!.

Raiden
  • 1
  • 1
  • thanks. Im still confused, why it is required to put [:] on x to mutate? – wanburana Jul 04 '20 at 11:45
  • well it is because if you won't do that only value of an object will be altered and it will be only visible in that function scope and will not get reflected in actual object. But when [:] this is put it creates and object and it is altered. Try playing with slicing of mutable and immutable objects it will get clear – Raiden Jul 08 '20 at 13:16