-1
myList = [5, 2]
def foo():
    myList[0] = 6

In the example above, myList is still mutated, though it is non-global and not passed in by parameter. This doesn't work however, if the variable is not a list.

9
  • I thought that if you want to mutate something in a function you have to call: global myList? Commented Jan 8, 2017 at 18:20
  • only when you reassign new value to given name. You are not in this case. Commented Jan 8, 2017 at 18:22
  • Not when mutating elements of a list list[0] = 4 will work while list = [4, 5] will not. Commented Jan 8, 2017 at 18:22
  • stackoverflow.com/questions/10262920/… Commented Jan 8, 2017 at 18:23
  • This question isn't a duplicate of the linked question, because the other question is about argument passing in Python and here no arguments are passed. Commented Jan 8, 2017 at 18:35

2 Answers 2

2

The scope rules are roughly like this:

  • Local scope: you define the variable inside a function
  • Enclosing scope: your function is inside another function (or multiple layers of functions), and one of the higher (enclosing) functions declared the variable
  • Global scope: the global scope (module or file)
  • Built-in: Any built-in values native to Python

This is known as the LEGB rule.

In your case, it is because you are not assigning a value to the name myList inside of foo(). You are only assigning a value to the 0 index of an existing list. Therefore the global value of myList is the scope you are using.

Sign up to request clarification or add additional context in comments.

Comments

2

myList is a global variable, though. It exists in the context of foo, where you access and modify one of its elements.

myList = [0, 5]

def foo():
    myList[0] = 6

print('Before foo: {}'.format(myList))
foo()
print('After foo: {}'.format(myList))

Output

Before foo: [0, 5]
After foo: [6, 5]

This doesn't work however, if the variable is not a list.

I assume that you tried something similar to the following:

a = 0

def bar():
    a = 6

print('Before bar: {}'.format(a))
bar()
print('After bar: {}'.format(a))

Output

Before bar: 0
After bar: 0

In this case, you don't observe any change in the global variable a because within bar you're assigning to a new local variable a which shadows the global variable of the same name. You set the local variable a to 6, which has no effect as the variable is discarded as soon as the function ends.

You can show that even simple integers declared in the global scope can be accessed within function scopes by running something like the following. In this case, we specify that the function should modify an existing global variable b rather than assigning to a new local one.

b = 0

def baz():
    global b
    b = 6

print('Before baz: {}'.format(b))
baz()
print('After baz: {}'.format(b))

Output

Before baz: 0
After baz: 6

2 Comments

Example of global keyword might be helpful here since it shows how one can assign to a global variable from the local scope. Python just assumes you don't normally mean that (and has no syntax for explicitly declaring a variable)
@pvg Step ahead of you. :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.