Python Functions: Arguments, Scope, Lambdas, and First-Class Behavior
Function Arguments: Positional, Keyword, and Default
When you call a function, you need to pass it data. Python gives you three ways to do that.
Positional arguments are matched by order. The first value goes to the first parameter, and so on.
| 1 | def greet(name, age): |
| 2 | print(fclass=class="syn-str">"syn-str">class="syn-str">"{name} is {age}") |
| 3 | |
| 4 | greet(class=class="syn-str">"syn-str">class="syn-str">"Alice", 30) class="syn-comment"># name=class=class="syn-str">"syn-str">class="syn-str">"Alice", age=30 |
Keyword arguments let you name the parameter explicitly, so order doesn't matter.
| 1 | greet(age=30, name=class=class="syn-str">"syn-str">class="syn-str">"Alice") class="syn-comment"># same result |
Default arguments give a parameter a fallback value if nothing is passed.
| 1 | def greet(name, age=25): |
| 2 | print(fclass=class="syn-str">"syn-str">class="syn-str">"{name} is {age}") |
| 3 | |
| 4 | greet(class=class="syn-str">"syn-str">class="syn-str">"Bob") class="syn-comment"># age defaults to 25 |
Common mistake: Never use a mutable object (like a list or dict) as a default value. It's shared across all calls.
| 1 | class="syn-comment"># BAD |
| 2 | def add_item(item, items=[]): |
| 3 | items.append(item) |
| 4 | return items |
| 5 | |
| 6 | class="syn-comment"># GOOD |
| 7 | def add_item(item, items=None): |
| 8 | if items is None: |
| 9 | items = [] |
| 10 | items.append(item) |
| 11 | return items |
args and *kwargs
Sometimes you don't know how many arguments a caller will pass. That's where these come in.
*args collects extra positional arguments into a tuple.
| 1 | def total(*args): |
| 2 | return sum(args) |
| 3 | |
| 4 | total(1, 2, 3) class="syn-comment"># 6 |
| 5 | total(10, 20) class="syn-comment"># 30 |
kwargs collects extra keyword** arguments into a dict.
| 1 | def display(**kwargs): |
| 2 | for key, value in kwargs.items(): |
| 3 | print(fclass=class="syn-str">"syn-str">class="syn-str">"{key}: {value}") |
| 4 | |
| 5 | display(name=class=class="syn-str">"syn-str">class="syn-str">"Alice", city=class=class="syn-str">"syn-str">class="syn-str">"London") |
You can combine them. The order must be: positional → args → keyword → *kwargs.
| 1 | def example(a, b, *args, key=class=class="syn-str">"syn-str">class="syn-str">"default", **kwargs): |
| 2 | pass |
These are useful when writing wrappers, decorators, or any function that needs to be flexible about what it receives.
Lambda Functions
A lambda is just a small, anonymous function — one that you write inline without using def.
| 1 | square = lambda x: x * x |
| 2 | square(5) class="syn-comment"># 25 |
Lambdas are limited to a single expression. No loops, no multiple statements.
They're most useful when passing a short function as an argument, like with sorted or map.
| 1 | names = [class=class="syn-str">"syn-str">class="syn-str">"Charlie", class=class="syn-str">"syn-str">class="syn-str">"Alice", class=class="syn-str">"syn-str">class="syn-str">"Bob"] |
| 2 | sorted(names, key=lambda name: len(name)) |
| 3 | class="syn-comment"># [class=class="syn-str">"syn-str">class="syn-str">"Bob", class=class="syn-str">"syn-str">class="syn-str">"Alice", class=class="syn-str">"syn-str">class="syn-str">"Charlie"] |
When to use them: Only when the function is truly throwaway and short. If you find yourself writing a complex lambda, define a proper function instead — it'll be easier to read and test.
Scope: Local, Global, and Nonlocal
Scope controls where a variable can be seen and modified.
Local scope means a variable lives inside a function. It disappears when the function returns.
| 1 | def foo(): |
| 2 | x = 10 class="syn-comment"># local to foo |
Global scope means a variable is defined at the top level of a file and can be read from anywhere.
| 1 | x = 10 |
| 2 | |
| 3 | def foo(): |
| 4 | print(x) class="syn-comment"># reads the global x — this works |
But if you try to assign to a global variable inside a function, Python creates a new local variable instead. To actually modify the global, you need to declare it.
| 1 | x = 10 |
| 2 | |
| 3 | def foo(): |
| 4 | global x |
| 5 | x = 20 class="syn-comment"># now modifies the global x |
Nonlocal handles the case where you have a nested function and want to modify a variable in the enclosing (but not global) function.
| 1 | def outer(): |
| 2 | count = 0 |
| 3 | |
| 4 | def inner(): |
| 5 | nonlocal count |
| 6 | count += 1 |
| 7 | |
| 8 | inner() |
| 9 | print(count) class="syn-comment"># 1 |
Rule of thumb: Avoid using global in production code. It makes functions harder to reason about and test. Prefer passing values in and returning them out.First-Class Functions
In Python, functions are objects. You can store them in variables, pass them to other functions, and return them from functions. This is what "first-class" means.
Storing a function in a variable:
| 1 | def say_hello(): |
| 2 | print(class=class="syn-str">"syn-str">class="syn-str">"Hello") |
| 3 | |
| 4 | greet = say_hello |
| 5 | greet() class="syn-comment"># Hello |
Passing a function as an argument:
| 1 | def run(func): |
| 2 | func() |
| 3 | |
| 4 | run(say_hello) class="syn-comment"># Hello |
Returning a function from a function:
| 1 | def make_multiplier(n): |
| 2 | def multiply(x): |
| 3 | return x * n |
| 4 | return multiply |
| 5 | |
| 6 | double = make_multiplier(2) |
| 7 | double(5) class="syn-comment"># 10 |
This last pattern — returning a function that "remembers" a value from its enclosing scope — is called a closure. It's the foundation of decorators and many functional patterns in Python.
Takeaways
- Use positional args for required inputs, keyword args for clarity, and defaults for optional config.
argsand*kwargsmake functions flexible — use them for wrappers and generic utilities.- Lambdas are useful inline, but don't overuse them. If it needs a name, write a real function.
- Variables follow LEGB scope: Local → Enclosing → Global → Built-in. Avoid
global; prefer returning values. - Functions are objects. Passing them around and returning them unlocks powerful patterns like closures and decorators.