Lambda Functions and Scope
Writing small anonymous functions with lambda, and how Python resolves variable scope.
2 min read
Not every function needs a name and a full def block. Python's lambda creates a small, throwaway function inline — and understanding scope explains exactly which variables that function (or any function) can see.
Lambda functions
square = lambda x: x ** 2
print(square(5)) # 25This is equivalent to:
def square(x):
return x ** 2A lambda can take multiple arguments and always consists of a single expression — whatever that expression evaluates to is returned automatically, with no return keyword and no statements allowed inside it.
add = lambda a, b: a + bWhere lambdas actually get used
Assigning a lambda to a variable, as above, is rarely the point — if it needs a name, a regular def is clearer. Lambdas earn their keep as short, inline arguments to functions that expect a function, most commonly sorted(), map(), and filter():
people = [("Ada", 36), ("Bob", 24), ("Carol", 30)]
# Sort by age instead of name
people.sort(key=lambda person: person[1])
# Transform every item
prices = [10, 20, 30]
with_tax = list(map(lambda p: p * 1.08, prices))
# Keep only items matching a condition
evens = list(filter(lambda n: n % 2 == 0, range(10)))In each case, key=, map(), and filter() need a function, not a value — the lambda supplies one without the ceremony of a separate def elsewhere in the file.
Scope: where a variable is visible
Python resolves a variable name by searching outward through a sequence of scopes, commonly summarized as LEGB: Local, Enclosing, Global, Built-in.
x = "global"
def outer():
x = "enclosing"
def inner():
x = "local"
print(x) # "local"
inner()
print(x) # "enclosing"
outer()
print(x) # "global"Each x here is a distinct variable in its own scope — assigning inside inner() doesn't touch outer()'s x, and neither touches the global one.
Reading vs. writing global state
A function can read a global variable without any special syntax:
counter = 0
def show_counter():
print(counter) # works fine, just reading
show_counter()But assigning to a name inside a function makes Python treat it as local by default — which is why this fails to do what it looks like it should:
def increment():
counter += 1 # UnboundLocalError
increment()Python sees the assignment and decides counter is local to increment, then finds it's referenced before being given a value locally. The global keyword tells Python you mean the outer variable:
def increment():
global counter
counter += 1In practice, reaching for global is usually a sign a function's logic could be reorganized — passing values in as parameters and returning results tends to make code easier to follow than functions that quietly reach out and mutate shared state.
Test what you just learned
4 quick questions. Get all of them right to unlock the next lesson.
You can take the quiz without an account — logging in just lets your result count toward your progress.