Python list += unexpected behavior in inner function [duplicate] - python

This question already has answers here:
Is it possible to modify a variable in python that is in an outer (enclosing), but not global, scope?
(9 answers)
UnboundLocalError trying to use a variable (supposed to be global) that is (re)assigned (even after first use)
(14 answers)
Closed 2 years ago.
I read in many places that += is an in-place operation, which does not create a new list. Given this, I would expect the inner function to be able to see and mutate the lst defined in outer(). Could someone explain what is going on here? I understand there are alternative ways to make it work as expected like lst.append(2). I am just trying to understand why it does NOT work.
There is a similar question regarding += on integers UnboundLocalError with nested function scopes
That question is easy to answer as integers are immutable so ctr += 1 actually declares a new name in the inner function, and that new name is referenced before a value is assigned. This argument does not apply to the case here since += on a list does not create new bindings.
def outer():
lst = [0]
def inner():
lst += [2]
inner()
outer()
UnboundLocalError: local variable 'lst' referenced before assignment

Related

How to understand global and local scopes in Python? [duplicate]

This question already has answers here:
UnboundLocalError trying to use a variable (supposed to be global) that is (re)assigned (even after first use)
(14 answers)
Using global variables in a function
(25 answers)
Closed 5 months ago.
I am a novice in Python and wondering the situation below.
x = 1
def func():
print(x)
x = 2
return x
So I got the UnboundLocalError: local variable 'x' referenced before assignment.
But if I right understand - Python read and execute code row by row.
So in first statement inside function "print(x)" it must just relay global variable x which eq. 1, but instead I got the error.
Please explain, I think it simple.
I think your problem was explained as well in the FAQ of python docs
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. Since the last statement in foo
assigns a new value to x, the compiler recognizes it as a local
variable. Consequently when the earlier print(x) attempts to print the
uninitialized local variable and an error results.

How to set variable within function def in python? [duplicate]

This question already has answers here:
UnboundLocalError trying to use a variable (supposed to be global) that is (re)assigned (even after first use)
(14 answers)
UnboundLocalError: local variable … referenced before assignment [duplicate]
(2 answers)
Closed 2 years ago.
I have a simple code like this:
temp = 100
def my_fun():
temp += 10
return temp
After I call this function my_fun() I get an error
local variable 'temp' referenced before assignment
What's wrong with my code? I set temp before I call it. But still an error.
Thanks to all.
Best would be to pass it in:
def my_fun(temp):
temp += 10
return temp
temp = 100
temp = my_fun(temp)
But if you really want to access it from the outer scope, then use:
global temp
Edit: I see you amended your question - the reason for the error is the scope of the var. Within the function that variable only exists at the function level, and since you've not actually assigned it or passed it in, it doesn't exist when you try and increment it.

Scope of variable and list in python [duplicate]

This question already has answers here:
UnboundLocalError trying to use a variable (supposed to be global) that is (re)assigned (even after first use)
(14 answers)
Is it possible to modify a variable in python that is in an outer (enclosing), but not global, scope?
(9 answers)
Closed 3 years ago.
I am curious why the following code generates error:
def test_method():
main_var = 0
main_list = list()
def sub_method():
print(main_list)
main_list.append(0)
print(main_list)
print(main_var)
main_var +=1
print(main_var)
sub_method()
Error
UnboundLocalError: local variable 'main_var' referenced before assignment
In particular, it does not complain about list, but does complain about variable.

UnboundLocalError: local variable 'r' referenced before assignment [duplicate]

This question already has answers here:
UnboundLocalError trying to use a variable (supposed to be global) that is (re)assigned (even after first use)
(14 answers)
Closed 9 years ago.
I'm having an issue with variable and function. Here is a simple code:
r = 0
list = ['apple','lime','orange']
def list_list(x):
for i in x:
r +=1
print r
list_list(list)
Error:
UnboundLocalError: local variable 'r' referenced before assignment
I know it must be something simple. I started to do my script using functions instead straight code.
You should rewrite your function to take r as an argument if you want to define it outside of your function:
def my_func(some_list, r=0):
# do some stuff
Basically, you have a problem with scope. If you need r outside of the function, just return it's value in a tuple:
def my_func(some_list, r=0):
# do some stuff
return new_list, r
my_list = [1,2,3,4,5]
different_list, my_outside_r = my_func(some_list, 0)
The r within the function isn't the same as the one outside the function, so it hasn't been set yet.
You shoudld put r = 0 inside the function. But if you want the length of the list just use len(list)
Also try to avoid naming variables same as builtin names like list.

Python scope, dictionary and variables difference? [duplicate]

This question already has answers here:
UnboundLocalError trying to use a variable (supposed to be global) that is (re)assigned (even after first use)
(14 answers)
Why isn't the 'global' keyword needed to access a global variable?
(11 answers)
Closed 6 months ago.
Python scope
I have the same question but slightly different.
number = 0
def incrementNumber():
number += 1
This one above does not work but this one below does why? Both are outside the function scope.
number = {'num':0}
def incrementNumber():
number['num'] += 1
First one works if I add the variable as global
number = 0
def incrementNumber():
global number
number += 1
Check out this blog post, it's similar to what you're doing. Specifically adam's comment.
You don't assign to dictionaryVar, you assign to dictionaryVar['A'].
So it's never being assigned to, so it's implicitly global. If you
were to actually assign to dictionaryVar, you'd get the behavior you
were "expecting".
In the first case int is not mutable, so when you do number +=1 your are really updating where number points. As you, in general, do not want changes to propagate up-scope with out
explicitly telling it to, python does a copy-on-write and gives you a local variable number. You than increment that variable and it is thrown away when the function returns
In the case of dictionaries, which are mutable, you are grabbing the up-scope reference and then mutating the underlying object, thus your addition propagates out of the function.
In the last case you have explicitly told python to not make number a local variable, thus the changes propagate out as you want.
related python closure local variables

Categories