Marc Scott
Marc Scott

Reputation: 65

Scope of lists in Python 3

This may be a very stupid question, but I'm a little uncertain as to why lists behave differently to other variables in Python 3, with regard to scope. In the following code...

foo = 1
bar = [1,2,3,4]

def baz():
    foo += 1
    bar[0]+=1

I understand why foo += 1 throws an error with regard to foo being outside of local scope. Why doesn't bar[0]+=1 throw the same error though?

Upvotes: 3

Views: 530

Answers (3)

thefourtheye
thefourtheye

Reputation: 239473

When you execute the code, you will get

 ....
     foo += 1
 UnboundLocalError: local variable 'foo' referenced before assignment

foo += 1 is actually evaluated like this. foo = foo + 1. So, you are adding 1 to the value of foo and storing it in a variable foo. Since there is an assignment happening, Python assumes that foo is a local variable. But, if it is a local variable, in the expression foo + 1, what would be the value of foo? Python couldn't answer this question. That is why it throws that error.

But, when you do bar[0] += 1, Python evaluates it like this bar[0] = bar[0] + 1. Since, it already knows what bar is, and you are just trying to replace the first element in it, it allows it. In the last case, we were creating a new local variable called foo by doing foo += 1, but here, we are just altering the same object. So Python allows this.

Upvotes: 1

Others
Others

Reputation: 3023

In python, you can't modify globals without the 'global' keyword. This is for clarity.

foo=1
def bar():
     global foo
     foo=2
bar()
#foo is now 2!

Since bar[0]+=foo modifies the an element of a list, not the value of the list variable itself, it is legal.

Upvotes: 2

Joe
Joe

Reputation: 47609

The variable foo points to an object (an integer). The variable baz points to an object (a list). If you try and reassign baz to another object you would get the error. But you're not, you're just calling a method on the list object, and anyone can do that.

Upvotes: 2

Related Questions