3

Why can we modify list with the append method but can't do the same with the list concatenation? I know about the local and global scope, I'm confused about why we can do it with append method, thanks in advance

some_list=[]

def foo():
    some_list.append('apple')


foo()
print(some_list)
#it works

with list concatenation

some_list=[]

def foo():
    some_list+=['apple']


foo()
print(some_list)
#UnboundLocalError: local variable 'some_list' referenced before assignment
Artyom
  • 31
  • 3
  • 6
    In your second example, there is an assignment to the variable name - that makes it a local variable by default, unrelated to the global variable of the same name. In the first example, the variable is unquestionably global, because there's nothing else it could possibly be. – jasonharper Jul 31 '22 at 18:34
  • Does this answer your question? [UnboundLocalError on local variable when reassigned after first use](https://stackoverflow.com/questions/370357/unboundlocalerror-on-local-variable-when-reassigned-after-first-use) – Himanshu Poddar Jul 31 '22 at 18:38
  • see: https://docs.python.org/3.8/faq/programming.html#what-are-the-rules-for-local-and-global-variables-in-python. "In Python, variables that are only referenced inside a function are implicitly global. If a variable is assigned a value anywhere within the function’s body, it’s assumed to be a local unless explicitly declared as global." – John M. Jul 31 '22 at 18:39

2 Answers2

1

Augmented operations like += reassign the original variable, even if its not strictly necessary.

Python's operators turn into calls to an object's magic methods: __iadd__ for +=. Immutable objects like int can't change themselves so you can't do an in-place += like you can in C. Instead, python's augmented methods return an object to be reassigned to the variable being manipulated. Mutable objects like lists just return themselves while immutable objects return a different object.

Since the variable is being reassigned, it has to follow the same scoping rules as any other variable. The reassignment causes python to assume that the variable is in the local namespace and you need the global keyword to override that assumption.

tdelaney
  • 73,364
  • 6
  • 83
  • 116
0

Local and global scopes apply to the variable itself, specifically what object it is referencing. The variable just points to an object in memory. You can't change the 'pointer' of the variable in a different local scope, but you can change the object that it points to. Here, you can use append because it changes the list object itself, the one stored in memory. It doesn't change what the variable some_list points to. On the other hand, the second example, you try to reassign some_list to refer to a new list that was created in combination with the old list. Since this can't happen, the interpreter now treats this some_list as a local variable separate from the other, gloabl one

Anonymous
  • 452
  • 2
  • 9
  • *On the other hand, the second example, you try to reassign some_list to refer to a new list that was created in combination with the old list.* This would be the case if `some_list` was another type of variable, but for lists, `+=` doesn't reassign to a new object, it actually performs a mutation (https://stackoverflow.com/questions/2347265/why-does-behave-unexpectedly-on-lists). So this is kind of a case of the parser not recognising that override of `+=`: the statement `some_list.extend(['apple'])` does exactly the same, but does not cause the same error. – slothrop Jul 31 '22 at 18:47
  • @slothrop: The parser has absolutely no idea what the types of any variables are, so it cannot possibly distinguish between a `+=` operation that reassigns the variable, and a `+=` operation that merely mutates the existing value. – jasonharper Jul 31 '22 at 19:20