4

I do not quite understand the difference between the following two similar codes:

def y(x):
    temp=[]
    def z(j):
        temp.append(j)
    z(1)
    return temp

calling y(2) returns [1]

def y(x):
    temp=[]
    def z(j):
        temp+=[j]
    z(1)
    return temp

calling y(2) returns UnboundLocalError: local variable 'temp' referenced before assignment. Why + operator generates the error? Thanks

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
3c.
  • 275
  • 2
  • 10

2 Answers2

11

Answer to the heading, the difference between + and "append" is:

[11, 22] + [33, 44,] 

will give you:

[11, 22, 33, 44]

and.

b = [11, 22, 33]
b.append([44, 55, 66]) 

will give you

[11, 22, 33 [44, 55, 66]] 

Answer to the error

This is because when you make an assignment to a variable in a scope, that variable becomes local to that scope and shadows any similarly named variable in the outer scope

The problem here is temp+=[j] is equal to temp = temp +[j]. The temp variable is read here before its assigned. This is why it's giving this problem. This is actually covered in python FAQ's.

For further readings, click here. :)

JGCW
  • 1,509
  • 1
  • 13
  • 25
  • Your first part shows that `+=` is more like `extend` than `append`. But `+=` isn't exactly like `temp=temp+[]`. In one the `id` changes, in the other it does not. The `iadd` docs claim that `x.__iadd__(y) <==> x+=y`. But apparently the scoping rule applies first. So that equivalence isn't exact either. – hpaulj Dec 08 '15 at 04:30
3

The UnboundLocalError occurs because, when you make an assignment to a variable in a scope, that variable is automatically considered by Python to be local to that scope and shadows any similarly named variable in any outer scope.

In the append function, you are not making an assignment per se, and therefore there is no scope error.

Ayush
  • 3,695
  • 1
  • 32
  • 42