Python change global variable in for loop

Actually I want to initialize because the iteration range is different. and Sorry I was asking if there is no function, i.e., I just want to run the below code

    iter = 0
    for i in 1:10
        global iter +=1
    end

This kind of “variable lifetime” is known as scoping. After reading this article, you will know the scoping rules of Python. Let’s start!

The 3 Scopes of Python

Python has 3 scopes:

  • Global: In the main part of the script. By default, this already contains the built-ins. You can access all global variables with
    Traceback (most recent call last):
    File "example.py", line 5, in <module>
    foo()
    File "example.py", line 2, in foo
    print(min([1, 2, 3]))
    UnboundLocalError: local variable 'min' referenced before assignment
    7
  • Enclosed: In the outer function, if this is a nested function
  • Local: Within the current function. You can access all local variables with
    Traceback (most recent call last):
    File "example.py", line 5, in <module>
    foo()
    File "example.py", line 2, in foo
    print(min([1, 2, 3]))
    UnboundLocalError: local variable 'min' referenced before assignment
    8 . Within the main script,
    Traceback (most recent call last):
    File "example.py", line 5, in <module>
    foo()
    File "example.py", line 2, in foo
    print(min([1, 2, 3]))
    UnboundLocalError: local variable 'min' referenced before assignment
    9

You can see all three in action here:

There is a crucial point here:

The scope of a variable is defined at compile-time!

For this reason, the following code throws an exception:

def foo():
print(min([1, 2, 3]))
min = lambda n: "local"
foo()

throws the exception:

Traceback (most recent call last):
File "example.py", line 5, in <module>
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment

The “global” statement

You can assign a value to a global variable in a function with the global statement:

x = "global"def foo():
global x
x = "local"
foo()
print(x) # gives "local"

I need this very rarely. To make sure that I don’t confuse anything, I like to use the

Traceback (most recent call last):
File "example.py", line 5, in <module>
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment
7 dictionary. In this case, I would rather use:

x = "global"def foo():
globals()["x"] = "local"
foo()
print(x) # gives "local"

The “nonlocal” statement

You can assign a value to an enclosed variable with the nonlocal statement:

x = "global"def foo():
x = "enclosed"
def bar():
nonlocal x
x = "local"
bar()
print(x) # gives "local"
foo()
print(x) # gives "local"

Confusing Examples

Image by wokandapix (source)

Append element vs ‘+= [element]’

xs = []def foo():
xs.append(42) # OK
foo()

vs

xs = []def foo():
xs +=[42] # UnboundLocalError: local variable 'xs'
# referenced before assignment
foo()

The reason why the first works but not the second is that the first one calls a function of xs. It never assigns a value to xs. The second one is equal to

xs = []def foo():
xs = xs + [42]
foo()

When Python parses the assignment

x = "global"def foo():
global x
x = "local"
foo()
print(x) # gives "local"
1 , the
x = "global"def foo():
global x
x = "local"
foo()
print(x) # gives "local"
2 is assigned the local scope. But in the local scope,
x = "global"def foo():
global x
x = "local"
foo()
print(x) # gives "local"
2 does not exist before
x = "global"def foo():
global x
x = "local"
foo()
print(x) # gives "local"
4 is executed. Hence the error.

In the first example with

x = "global"def foo():
global x
x = "local"
foo()
print(x) # gives "local"
5 , the global scope of
x = "global"def foo():
global x
x = "local"
foo()
print(x) # gives "local"
2 is used. Hence we don’t face any issue, because it is defined in the global scope.

Global scope DOES fall back to built-ins

# prints 1
print(min([1, 2, 3]))
min = lambda n: "local"

but the same does not work in a local scope

# UnboundLocalError: local variable 'min' referenced before assignment
def foo():
print(min([1, 2, 3]))
min = lambda n: "local"
foo()

The reason is that

Traceback (most recent call last):
File "example.py", line 5, in <module>
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment
9 within the global scope. Although built-ins are a bit special, they kind of live in the global scope.

Assignment

This one is confusing to people with a Java, C, or C++ background. This is valid Python code:

Traceback (most recent call last):
File "example.py", line 5, in <module>
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment
0

But in Java you need to declare it upfront to be able to use the variable after the loop:

Traceback (most recent call last):
File "example.py", line 5, in <module>
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment
1

mypy

mypy is a wide-spread type-checker for Python.

Traceback (most recent call last):
File "example.py", line 5, in <module>
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment
2

So mypy doesn’t like that you assign the string “foo” to

x = "global"def foo():
global x
x = "local"
foo()
print(x) # gives "local"
8 , because it first read took the
x = "global"def foo():
global x
x = "local"
foo()
print(x) # gives "local"
9 path and assumed that
x = "global"def foo():
global x
x = "local"
foo()
print(x) # gives "local"
8 would be an integer.

Then you might want to do this:

Traceback (most recent call last):
File "example.py", line 5, in <module>
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment
3

You can see that mypy assumes the

x = "global"def foo():
global x
x = "local"
foo()
print(x) # gives "local"
8 should be the same type in both cases. It’s reasonable because otherwise the following analysis might get extremely complicated.

The next try might be:

Traceback (most recent call last):
File "example.py", line 5, in <module>
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment
4

That should have been expected. Assigning

x = "global"def foo():
globals()["x"] = "local"
foo()
print(x) # gives "local"
2 is not possible to a type which does not include
x = "global"def foo():
globals()["x"] = "local"
foo()
print(x) # gives "local"
2 — and adding
x = "global"def foo():
globals()["x"] = "local"
foo()
print(x) # gives "local"
2 to that type might cause many more issues down the road.

You can do this:

Traceback (most recent call last):
File "example.py", line 5, in <module>
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment
5

But I can also see when this feels strange. What might be cleaner is this:

Traceback (most recent call last):
File "example.py", line 5, in <module>
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment
6

Summary

We have seen the three types of scopes in Python: Local, Enclosed, and global. We’ve seen that you can access globals with the

x = "global"def foo():
globals()["x"] = "local"
foo()
print(x) # gives "local"
5 keyword or over the
Traceback (most recent call last):
File "example.py", line 5, in <module>
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment
7 dictionary. Locals can be accessed with the
Traceback (most recent call last):
File "example.py", line 5, in <module>
foo()
File "example.py", line 2, in foo
print(min([1, 2, 3]))
UnboundLocalError: local variable 'min' referenced before assignment
8 dictionary and enclosed variables with the
x = "global"def foo():
globals()["x"] = "local"
foo()
print(x) # gives "local"
8 keyword. Keep that in mind and Python scoping should make sense 🙂

How do I change the value of a global variable in Python?

Global Keyword. Global keyword is used to modify the global variable outside its current scope and meaning. It is used to make changes in the global variable in a local context. The keyword 'Global' is also used to create or declare a global variable inside a function.

Can you change variable in while loop Python?

Unlike if statements, the condition in a while loop must eventually become False. If this doesn't happen, the while loop will keep going forever! The best way to make the condition change from True to False is to use a variable as part of the Boolean expression. We can then change the variable inside the while loop.

Can you modify a global variable?

Functions can access global variables and modify them. Modifying global variables in a function is considered poor programming practice. It is better to send a variable in as a parameter (or have it be returned in the 'return' statement).

How do you change the variable name in a for loop in Python?

To change the name of a variable in a loop in Python, you can simply reassign a new value to the variable. For example: for i in range(10): x = i.