0

this is a follow up question to Variable scope, immutable vs mutable, in terms of +=.

def update():
    L.extend([1])
L=[1,2,3]
update()
print(L)

outputs [1,2,3,1]

but

def update1():
    L=L+[1]
L=[1,2,3]
update1()
print(L)

outputs UnboundLocalError: local variable 'L' referenced before assignment

but

def update2():
    L[0]=L[0]+1
L=[1,2,3]
update2()
print(L)

outputs [2,2,3]

i understand that update1() produces an UnboundLocalError because, when an assignment to L is made inside update1(), python marks L as a local variable with no assigned value. so L+=[1] gives an error, since a variable is being read before being assigned.(And this is also why "you cannot modify a variable defined outside the current scope")

And i understand that update() works because no assignment to L was made, so python did not create a local variable L( with no assigned value). hence, according to the LEGB rule, the extend method is then applied to global variable L.

But i do not understand why update2() works. I was thinking that one or all of the following things could happen

  1. python can give a syntax error, or maybe a type error() (since L[0] is not a valid variable name)
  2. python can give a type error, if L gets marked as a local variable with no assigned value.
  3. UnboundedLocalError

but it is none of the above

Should it (update2()) be considered as an exception, or is there an explanation behind why update(2) works the way it does?

martineau
  • 119,623
  • 25
  • 170
  • 301
abhishek
  • 121
  • 4
  • 4
    `L[0] = foo` becomes `L.__setitem__(0, foo)` - you're just looking up an attribute (like `extend`) on `L`, not trying to assign to that identifier. – jonrsharpe Dec 31 '19 at 16:11
  • 2
    You were partially right. L is a name that references some object. When you do `L=`, you assign something to the name. However, when you do L[0], you don't change the object that L references, you modify insides - it literally looks up the object, then changes whatever item was at 0th index. At this point the name doesn't matter, eg you could've done `A=L; A[0]+=1` - L would be changed anyway, because they reference the same object, but A is a local variable. – h4z3 Dec 31 '19 at 16:20

0 Answers0