Skip to content
Forge Learn/Functions

Scope, Closures & Lambda Functions

6 min read

You'll learn to

  • -Distinguish local scope from global scope, and know when `nonlocal`/`global` are needed
  • -Explain what a closure is and why a nested function can "remember" variables from its enclosing function
  • -Write and use `lambda` expressions where a full function definition would be overkill

This chapter covers where variables live and how long they last (scope), a powerful pattern that falls directly out of scope rules (closures), and a compact syntax for tiny one-off functions (lambdas). Closures in particular are worth reading slowly - they are the exact mechanism behind memoization and caching decorators, which the Algorithms phase leans on heavily.

Local vs. Global Scope

A variable created inside a function is local to that function - it exists only while the function is running and disappears afterward. A variable created at the top level of a module is global - visible everywhere in that file. A function can read a global variable without any special syntax, but by default it cannot reassign one.

Reading vs. reassigning a global

In practice, reaching for `global` is usually a sign to reconsider the design - passing values in as parameters and returning results is almost always clearer, and it is exactly what a well-written function (or method on a class) does instead.

Closures: Functions That Remember

A closure happens when a nested function references a variable from its enclosing (outer) function, and that inner function is then returned or otherwise used outside the outer function's call. The inner function keeps a live reference to that variable - it does not just copy the value once.

A closure that remembers a starting value

`nonlocal` tells Python that `count` refers to the variable in the enclosing function's scope, not a brand-new local variable - it is the closure equivalent of `global`, one scope level up instead of all the way to the module. Each call to `make_counter` creates a fresh, independent `count` that `increment` keeps a private reference to. This "a function that returns a function which remembers state" shape is exactly what a memoization cache looks like under the hood - keep this example in mind when the Algorithms phase introduces caching decorators.

Lambda Functions

A `lambda` is a small, anonymous, single-expression function. It is not a different kind of function - it is just a compact syntax for cases where defining a full named function with `def` would be more ceremony than the logic deserves.

lambda vs. def for the same logic
  • -A lambda can only contain a single expression - no statements, no assignments, no loops.
  • -The most common real use is as the `key=` argument to `sorted()`, `.sort()`, `min()`, and `max()`.
  • -If a lambda is getting hard to read, it should be a named function instead - readability always wins over compactness.
Check Yourself1 / 3

Why does `count = count + 1` inside a function raise `UnboundLocalError` if `count` is only defined at module level?

ScaleDojo Logo
Initializing ScaleDojo