4

I thought list.extend and "+=" on list basically do the same thing - extends the list without creating new list.

I expect following code to print [42, 43, 44, 45, 46] but I'm getting UnboundLocalError: local variable 'x' referenced before assignment

Why I'm getting this error? Where is the difference?

def f():
    x.extend([43, 44])
def g():
    x += ([45, 46])
x = [42]
f()
g()
print x

I tried this in python2.7.3 and python3.4.0.

yafinee
  • 43
  • 4

1 Answers1

12

+= gives an object the opportunity to alter the object in-place. But this depends on the type of x, it is not a given that the object is altered in place.

As such, += still needs to re-assign to x; either x.__iadd__() returns x, or a new object is returned; x += something is really translated to:

x = x.__iadd__(something)

Because += includes an assignment, x is marked as a local in g().

x.extend() on the other hand, is not an assignment. The programmer has decided that x is always an object with an .extend() method and uses it directly. Python sees no assignment and x is marked as a global.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • I agree. x.__iadd__ is returning a list, source here: http://hg.python.org/cpython/file/db842f730432/Objects/listobject.c#l914 – yafinee May 09 '14 at 13:04