Enclosing scope in Python - Time & Space Complexity
Start learning this pattern below
Jump into concepts and practice - no test required
Let's explore how the time it takes to run code changes when we use variables from an enclosing scope inside a function.
We want to see how this affects the speed as the input grows.
Analyze the time complexity of the following code snippet.
def multiplier(factor):
def multiply(number):
return number * factor
return multiply
times3 = multiplier(3)
result = times3(10)
This code creates a function that remembers a number from outside and uses it to multiply another number.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: There are no loops or repeated steps here; the multiply function just does one multiplication.
- How many times: The multiplication happens once per call to the inner function.
Explain the growth pattern intuitively.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 multiplications if called 10 times |
| 100 | 100 multiplications if called 100 times |
| 1000 | 1000 multiplications if called 1000 times |
Pattern observation: The time grows directly with how many times you call the inner function, not because of the enclosing scope.
Time Complexity: O(n)
This means the time grows in a straight line with the number of times you use the inner function.
[X] Wrong: "Using variables from outside the function makes the code slower for each call."
[OK] Correct: The inner function just uses the remembered value directly; it doesn't add extra loops or steps, so speed depends on how many times you call it, not on the enclosing scope.
Understanding how functions remember outside values helps you write clear and efficient code, a skill that shows you know how to manage data and speed well.
"What if the inner function had a loop inside it? How would the time complexity change?"
Practice
enclosing scope mean in Python functions?Solution
Step 1: Understand function nesting
In Python, functions can be defined inside other functions, creating an inner and outer function relationship.Step 2: Access rules for variables
Inner functions can use variables defined in their outer functions, which is called the enclosing scope.Final Answer:
Inner functions can access variables from outer functions -> Option AQuick Check:
Enclosing scope = inner function accesses outer variables [OK]
- Thinking all variables inside functions are global
- Believing inner functions cannot use outer variables
- Confusing local and global scopes
Solution
Step 1: Understand variable modification rules
To change a variable from an outer (enclosing) function inside an inner function, Python requires thenonlocalkeyword.Step 2: Differentiate from global
globalis for variables at the module level, not enclosing functions.Final Answer:
Usenonlocalkeyword inside the inner function -> Option CQuick Check:
Modify outer variable = use nonlocal [OK]
- Using 'global' instead of 'nonlocal' for outer function variables
- Trying to assign without any keyword causing UnboundLocalError
- Using a non-existent 'outer' keyword
def outer():
x = 5
def inner():
return x + 3
return inner()
print(outer())Solution
Step 1: Trace variable usage
Variablexis defined inouter()as 5. The inner function returnsx + 3, which is 8.Step 2: Function call and return
outer()callsinner()and returns its result, soprint(outer())prints 8.Final Answer:
8 -> Option DQuick Check:
Inner uses outer x=5, returns 5+3=8 [OK]
- Expecting an error due to variable scope
- Confusing inner return value with outer variable
- Thinking inner cannot access outer variables
def outer():
x = 10
def inner():
x = x + 5
return x
return inner()
print(outer())Solution
Step 1: Analyze variable assignment in inner()
Insideinner(),x = x + 5tries to modifyx. Python treatsxas local but it is used before assignment.Step 2: Understand error cause
This causes anUnboundLocalErrorbecausexis referenced before assignment locally. The fix is to declarenonlocal x.Final Answer:
UnboundLocalError because inner tries to modify x without nonlocal -> Option BQuick Check:
Modify outer var inside inner needs nonlocal [OK]
- Assuming it prints 15 without error
- Confusing UnboundLocalError with NameError
- Ignoring the need for 'nonlocal' when modifying outer vars
def counter():
count = 0
def increment():
nonlocal count
count += 1
return count
return increment
c = counter()
print(c())
print(c())
print(c())What will be the output?
Solution
Step 1: Understand closure with nonlocal
Thecounter()function returnsincrement(), which modifiescountusingnonlocal. This keepscountpersistent across calls.Step 2: Trace calls to c()
Each call toc()increasescountby 1 and returns it. So outputs are 1, then 2, then 3.Final Answer:
[1, 2, 3] -> Option AQuick Check:
Closure with nonlocal increments count each call [OK]
- Expecting count to reset each call
- Confusing nonlocal with global
- Thinking it will raise an error without global
