ASAmol Shukla
Projects
Courses
Prompts
Skills
Contact
Resume
Course Outline
Syllabus Overview

Complete Python Course: From Zero to Professional

Courses/Complete Python Course: From Zero to Professional/Lesson 13: Lambda, *args & **kwargs
40 mins lesson duration•8 mins read

Lesson 13: Lambda, *args & **kwargs

Anonymous one-line functions and flexible functions that accept any number of arguments.

Lambda — Tiny Anonymous Functions

A lambda is a one-line function without a name:

double = lambda x: x * 2
print(double(5))   # 10

It is exactly equivalent to def double(x): return x * 2, but written as an expression. Lambdas shine where you need a quick, throwaway function — especially as a sort key or with map/filter.

What You'll Learn in This Lesson

  • Write lambdas and use them as sort keys
  • Accept any number of arguments with *args
  • Accept any number of keyword arguments with **kwargs
  • Unpack sequences and dicts with * and **

Lambda as a Sort Key

The most common lambda use case — custom sorting:

products = [
    {"name": "Laptop", "price": 800},
    {"name": "Mouse", "price": 25},
    {"name": "Monitor", "price": 300},
]
products.sort(key=lambda p: p["price"])
# Sorts by price — ['Mouse', 'Monitor', 'Laptop']

The lambda receives each item and returns the value to sort by. You can also sort by length, last letter, or any computed property:

words = ["apple", "banana", "cherry"]
print(sorted(words, key=lambda w: w[-1]))   # sort by last letter

Mental model: each item gets a "score tag" from the lambda, then items are ordered by their tags.

Other classic lambda uses:

# map: apply to every item
squares = list(map(lambda x: x ** 2, [1, 2, 3]))     # [1, 4, 9]

# filter: keep items passing the test
evens = list(filter(lambda x: x % 2 == 0, range(10)))  # [0, 2, 4, 6, 8]

# max with a key
longest = max(["python", "ai", "code"], key=len)      # 'python'

In modern Python, list comprehensions often replace map/filter — but lambdas with key= in sort/max/min remain irreplaceable.


*args — Any Number of Positional Arguments

Putting *args in a function collects all extra positional arguments into a tuple:

def total(*args):
    return sum(args)

print(total(1, 2, 3))    # 6
print(total(5, 10))      # 15
print(total())           # 0

The name args is a convention — the * is what matters. This pattern is perfect for sums, averages, and flexible APIs.

Mental model: *args is a funnel that pours any number of loose values into one bag (a tuple). The bag arrives inside the function ready to loop over.


**kwargs — Any Number of Keyword Arguments

**kwargs collects extra named arguments into a dictionary:

def profile(name, **kwargs):
    print(f"Name: {name}")
    for key, value in kwargs.items():
        print(f"  {key}: {value}")

profile("Amol", role="Trainer", city="Mumbai")
# Name: Amol
#   role: Trainer
#   city: Mumbai

Frameworks use this to pass arbitrary options to functions without exploding the signature.

Mental model: **kwargs is a coat-check desk — every named item (name=value) is hung on a labeled hook in a dictionary.


Parameter Order — The Golden Rule

The order is fixed:

def f(normal, *args, keyword_only, **kwargs):
  1. Normal parameters
  2. *args
  3. Keyword-only parameters (after *)
  4. **kwargs

Keyword-only parameters (after a bare *) can only be passed by name — they protect against accidental misordering:

def connect(host, *, port=443):
    print(host, port)

connect("example.com")              # example.com 443
connect("example.com", port=8080)   # example.com 8080
# connect("example.com", 8080)      # TypeError! port is keyword-only

Unpacking with * and **

The * and ** also work in reverse — unpacking collections when calling:

def add(a, b, c):
    return a + b + c

nums = [1, 2, 3]
print(add(*nums))              # 6  — list unpacked into 3 args

config = {"a": 1, "b": 2, "c": 3}
print(add(**config))           # 6  — dict unpacked into keyword args

A real-world use — forwarding arguments. Wrappers and decorators (Lesson 14) capture everything with *args, **kwargs and forward it unchanged:

def logged_call(func):
    def wrapper(*args, **kwargs):
        print("Calling", func.__name__)
        return func(*args, **kwargs)   # forward everything
    return wrapper

When Lambdas Work Best — and When Not

✅ Use a lambda ❌ Use a def
Sort keys More than one expression
Passing behavior to map/filter Statements (if, loops)
Tiny one-off logic Anything you'd reuse by name

Keep lambdas to ONE expression. If it needs statements, write a def.


Common Mistakes to Avoid

  • Mistake: Writing lambda x: if x > 0: ... — Fix: lambdas cannot contain statements; use a def.
  • Mistake: Ordering parameters wrong (def f(**kwargs, *args)) — Fix: follow the golden order.
  • Mistake: Capturing a loop variable in a lambda — Fix: give the lambda a default: lambda x, i=i: ....
  • Mistake: Forgetting * when calling add(*nums) — Fix: without the star, you pass a single list as one argument.
  • Mistake: Naming the parameters args/kwargs and thinking the names matter — Fix: the */** syntax is what does the work.

Professional Tips & Tricks

  • Use lambdas only for tiny logic; for anything complex, def a real function.
  • *args is perfect for variadic sums, logs, and wrappers that must pass arguments through.
  • **kwargs lets you write configurable functions without exploding the signature.
  • Use bare * to force keyword-only arguments and prevent misordering bugs.
  • In decorators and wrappers, always forward *args, **kwargs unchanged.

Key Takeaways

  • lambda x: expr is a nameless one-expression function.
  • *args → tuple of extra positional args; **kwargs → dict of extra keyword args.
  • Parameter order: normal → *args → keyword-only → **kwargs.
  • *list and **dict unpack when calling functions.
  • Lambdas shine as key= functions for sort/max/min.

Next up: Scope, closures & decorators — the professional power tools.

Interactive Lesson Code Snippet
# Lambda as a sort key
products = [
    {"name": "Laptop", "price": 800},
    {"name": "Mouse", "price": 25},
    {"name": "Monitor", "price": 300},
]
products.sort(key=lambda p: p["price"])
print("Cheapest first:", [p["name"] for p in products])

# *args collects positional arguments into a tuple
def total(*args):
    return sum(args)

print("total(1,2,3):", total(1, 2, 3))
print("total(5, 10):", total(5, 10))

# **kwargs collects keyword arguments into a dict
def profile(name, **kwargs):
    print(f"Name: {name}")
    for key, value in kwargs.items():
        print(f"  {key}: {value}")

profile("Amol", role="Trainer", city="Mumbai")
Language: python

Lesson Code (Python)

# Lambda as a sort key
products = [
    {"name": "Laptop", "price": 800},
    {"name": "Mouse", "price": 25},
    {"name": "Monitor", "price": 300},
]
products.sort(key=lambda p: p["price"])
print("Cheapest first:", [p["name"] for p in products])

# *args collects positional arguments into a tuple
def total(*args):
    return sum(args)

print("total(1,2,3):", total(1, 2, 3))
print("total(5, 10):", total(5, 10))

# **kwargs collects keyword arguments into a dict
def profile(name, **kwargs):
    print(f"Name: {name}")
    for key, value in kwargs.items():
        print(f"  {key}: {value}")

profile("Amol", role="Trainer", city="Mumbai")

Console Output

Cheapest first: ['Mouse', 'Monitor', 'Laptop']
total(1,2,3): 6
total(5, 10): 15
Name: Amol
  role: Trainer
  city: Mumbai

Code Visualization Tips

  • 🧠Picture *args as a funnel collecting loose items into one bag (tuple).
  • 🧠Picture **kwargs as a coat-check desk collecting named items into a labeled cabinet (dict).
  • 🧠For sort keys, visualize each item getting a 'score tag' from the lambda, then being ordered by that tag.

Professional Tips & Tricks

  • ⚡Use lambdas only for tiny logic; for anything complex, def a real function.
  • ⚡*args is perfect for variadic sums, logs, and wrappers that must pass arguments through.
  • ⚡**kwargs lets you write configurable functions without exploding the signature.

Python Code Judge & Practice Arena

LeetCode Style

Run real Python 3.12 WebAssembly code directly in your browser against automated test suites.

Solved:0 / 20
0 / 370 XP
Challenges:
Problem 1 of 20

Problem 1: Variadic Aggregator 1

Easy+10 XP
Write a function `flexible_summary_1(*numbers, scale=1, **labels)` that multiplies sum(numbers) by scale and returns a dict with 'total' and all keyword labels.
Sample Test Cases:
Input: flexible_summary_1(1, 2, 3, scale=2, user='Amol')
Expected: {'total': 12, 'user': 'Amol'}
Input: flexible_summary_1(10, 20)
Expected: {'total': 30}
main.pyPython 3.12 (WASM)
1
2
3
4
5
6
7
8
9
10
11
12
Press Run Code to test or Submit to verify test cases

Test Your Knowledge

Instant feedback

Quick Check: Lesson 13: Lambda Functions, *args, **kwargs & Unpacking

1 / 20
What is the output of this lambda function? sq = lambda x: x ** 2 print(sq(5))

Up next · Continue learning

Scope, Closures & Decorators

LEGB scoping rules, closures that remember, and decorators that wrap functions with extra behavior.

10 mins read55 mins
Start next lesson
Previous: Functions — Reusable Building BlocksNext: Scope, Closures & Decorators
Made withbyAmol Shukla·amolshukla.online
ASAmol Shukla

AI Developer, Trainer & Agentic AI Expert building practical learning systems and real-world AI applications.

Explore

  • Projects
  • Courses
  • Prompts
  • Skills
  • Contact
  • Experience
  • Blogs

Connect

  • Resume
  • Contact
© 2026 Amol Shukla·Created withbyamolshukla.online
Back to top