Skip to content

Intermediate · Functions · topic 21 of 50 · 25 min

Scope: where variables live

Explanation

A variable made inside a function is local: it exists only inside that function. A variable made at the top of the file is global and can be read everywhere. Python looks up names in the order Local, Enclosing, Global, Built-in. The global and nonlocal keywords let a function change an outer variable, and lambda makes small one-line functions.

Where does a name live?

The scope of a variable is the part of the program where that name can be used. A variable created inside a function is local: it lives only inside that function, while the function runs. A variable created outside all functions, at the top level of the file, is global: it can be read everywhere.

Think of it like this: Think of nicknames. At home your family calls you "Chintu", but at school nobody knows that name. The home nickname is local to your house. Your real name, printed on your Aadhaar card, is known everywhere: it is global.
python
city = "Mumbai"

def show():
    city = "Pune"
    print("inside:", city)

show()
print("outside:", city)
The city inside show() is a separate local variable. Shows inside: Pune, then outside: Mumbai. The global one did not change.
output
def make_bill():
    total = 500

make_bill()
print(total)
NameError: name 'total' is not defined. total was local to make_bill and disappeared when the function ended.

LEGB: how Python finds a name

When you use a name, Python searches up to four places in this order and uses the first one it finds. The order is called LEGB:

  1. Local: inside the current function.
  2. Enclosing: inside an outer function, when this function is written inside another one.
  3. Global: at the top level of the file.
  4. Built-in: the names Python itself gives you, like print, len and sum.

UnboundLocalError

If a function ASSIGNS to a name anywhere in its body, Python treats that name as local in the whole function. So reading it before the assignment fails, even when a global with the same name exists.

output
count = 0

def add_visit():
    count = count + 1
    return count

add_visit()
UnboundLocalError: cannot access local variable 'count' where it is not associated with a value.

The global keyword, and why to avoid it

python
count = 0

def add_visit():
    global count
    count = count + 1
    return count

add_visit()
add_visit()
print(count)
global count tells Python to use the global variable, so the function can change it. Shows 2.
Careful: global works, but it makes programs hard to follow, because any function can change the value at any time. The better way is to pass the value in as an argument and return the new value: count = add_visit(count).

nonlocal: changing a variable of the outer function

python
def make_counter():
    count = 0
    def step():
        nonlocal count
        count += 1
        return count
    return step

counter = make_counter()
print(counter(), counter(), counter())
step is written inside make_counter. nonlocal count means "use the count of the enclosing function". Shows 1 2 3.

lambda: a tiny one-line function

python
double = lambda n: n * 2
print(double(21))

items = [("rice", 50), ("oil", 160), ("salt", 20)]
print(sorted(items, key=lambda item: item[1]))
lambda makes a small function without def: lambda inputs: result. It is handy for key= in sorted. Here the list is sorted by price, cheapest first.
Tip: Use lambda only for very short expressions, mostly as the key for sorted, min or max. If it needs more than one simple expression, write a normal def with a good name.

Watch the lesson

Scope: where variables live · 1/7

Scope

In this lesson you will learn where variables live, which is called scope.

Prefer a video by a teacher? Find free videos on “python variable scope global nonlocal lambda tutorial” on YouTube ↗

In real life: GST on a shopping cart

A billing program keeps the GST rate in one global constant, written in capital letters so everyone knows it should not change. Functions read it but never change it. Everything else, like the tax on one item, stays local inside the function, so it cannot clash with other parts of the program.

python
GST_RATE = 18

def price_with_gst(price):
    tax = price * GST_RATE / 100
    return price + tax

cart = [100, 250, 40]
total = 0
for p in cart:
    total += price_with_gst(p)
print("Total with GST: Rs", round(total, 2))
Shows Total with GST: Rs 460.2. The variable tax exists only inside the function.

Practice (0/3 done)

Task 1 · Code · Python

This add_visit() function crashes with UnboundLocalError because it changes the global variable visits. Add one line so that it updates the global visits and returns the new value.

Task 2 · Code · Python

items is a list of (name, price) tuples. Write a function cheapest_first(items) that returns a new list sorted by price, lowest first. Use sorted() with key=lambda.

Task 3 · Code · Python

make_counter() should return a function. Each call of that function returns the next number: 1, then 2, then 3. Right now step() crashes because it changes count from the outer function. Fix it with one line.

Quick quiz

Question 1

1.A variable is created inside a function. Where can you use it?

Question 2

2.What does LEGB stand for?

Question 3

3.x = 1, then def f(): x = 2, then f() and print(x). What is shown?

Question 4

4.Which keyword lets a nested function change a variable of its outer function?

Question 5

5.What does (lambda n: n + 10)(5) give?

Read more (free)

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

← Previous: *args and **kwargs