4

2I'm relatively new to Python (using 3.3.3) and have a list related question. When modifying a global list variable inside a function (please, no lectures on the evils of global variables), you typically do not need to declare the list with the global keyword inside the function - provided you stick to list methods. In particular, you may not use augmented addition without first using the global keyword. What surprises me is that using augmented addition outside the function clearly isn't modifying the list variable (only the list contents), and so I would expect to be allowed to use it inside a function without using the global keyword. Here are two examples that I can't reconcile:

list_1 = []

def my_func():
    list_1.append(0)
    #list_1 += [0]

my_func()
print('list_1 =', list_1)

This prints list_1 = [0], as expected, while the commented out augmented addition operation generates a complaint about using a local variable before assignment.

Here's an example that I can't reconcile with the previous one:

list_1 = [0]
list_2 = list_1
list_1 += [1]
print('list_2 =', list_2)

This prints list_2 = [0, 1], which suggests to me that list_1 += [1] did not modify the list_1 variable. I'm aware that list_1 = list[1] + [1] qualifies as modifying list_1, but augmented addition doesn't seem to. Why does augmented addition, inside a function, require use of the global keyword? Thanks for any help understanding this.

5
  • 1
    Did you try printing out list_1 to check your hypothesis that list_1 += [1] didn't modify list_1? Commented May 2, 2014 at 20:29
  • You say "This prints list_2 = [0, 1], which suggests to me that list_1 += [1] did not modify the list_1 variable." Why does that suggest that to you? Commented May 2, 2014 at 20:34
  • @BrenBarn I believe Jon means that list_1 += [1] did not cause list_1 to point to a different list, whereas list_1 = list_1 + [1] creates a new list and has list_1 point to that new list. Commented May 2, 2014 at 20:38
  • @ Rob Watts Yes, that's exactly what I mean. Commented May 2, 2014 at 22:51
  • possible duplicate of UnboundLocalError in Python Commented May 9, 2014 at 12:48

1 Answer 1

5

The problem is when a function body is parsed all the variables used in either normal assignments or augmented assigments are considered as local variables, so when the function gets called Python will not look for those variables in global scope hence it will raise an error. Hence you need to specify those variables as global to tell Python to look for them in global scope.

Another alternative is to use list.extend() instead of +=.

Related:

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

11 Comments

I would say it is a matter of readability and consistency. if list_1 was an int, += would reassign, and therefore it would make sense that global must be used. It makes sense that += will have the same effect on globalness for all types
FYI, OP asked about Python 3.x, but your first link is the Python 2.x docs.
@njzk2 If I got your point correctly then for immutable types it doesn't matter whether you use += or plain =, because in any way it going to update only a single variable and all the other references are going to be unaffected. So, += is going to have a different effect based on the object's type.
@RobWatts Updated the link, except the nonlocal part they're essentially the same.
@Aशwiniचhaudhary: yes. If you look at a = 3; id(a); a += 1; id(a) vs lst = []; id(lst); lst += [0]; id(lst), you'll see that += reassigns the immutable type (has to, obviously) but does not reassign the list.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.