Python Functions Explained: Lambda, Recursion, Generators and Decorators
A lambda function in Python is a small, anonymous function defined with the lambda keyword. It takes any number of arguments but only a single expression, which Python evaluates and returns automatically. No return statement needed. Lambda functions are best for short, inline logic inside sorted(), map() or filter().
- Key Takeaway 1: Use
deffor any function you’ll call more than once or that needs multiple lines of logic. - Key Takeaway 2: A lambda function in Python shines inside
sorted(),map()andfilter()where you need a quick one-liner. - Key Takeaway 3: Recursion needs a base case or your program will crash with a
RecursionError. - Key Takeaway 4: Generators use
yieldinstead ofreturnand produce values one at a time, saving memory when datasets are large. - Key Takeaway 5: Decorators wrap a function to extend its behaviour without editing its source code.
How to Create a Function in Python: The Basics First
You define a function in Python using the def keyword, followed by a name, parentheses and a colon. Everything indented below that line is the function body. The return statement sends a value back to the caller. If you skip return, Python returns None by default.
Here’s the simplest possible example: def greet(name): return f"Hello, {name}!". Call it with greet("Priya") and you get "Hello, Priya!". The hard part isn’t the syntax — it’s understanding the different ways you can pass data into a function.
Positional, Keyword and Default Arguments
Python supports three argument styles and you’ll use all three. Positional arguments must appear in the exact order you defined them. Keyword arguments let you name each value at the call site so order doesn’t matter. Default arguments give a parameter a fallback value when the caller doesn’t supply one.
Example: def register(name, course="Python", fee=5000). If you call register("Arjun"), Python uses the defaults. Call register("Arjun", fee=8000) and you’re mixing positional and keyword styles. Default arguments must always come after positional ones in the definition.
What is *args and **kwargs in Python?
*args lets a function accept any number of positional arguments as a tuple. **kwargs does the same for keyword arguments, collecting them into a dictionary. You’ll see both constantly in open-source Python libraries and framework code.
Think of a function that logs exam scores: def log_scores(*args) can accept two scores or twenty without changing the signature. Add **kwargs and you can also pass named metadata like subject="Maths". According to the official Python documentation, this pattern is central to writing flexible, reusable APIs. If you’re building tools for data pipelines, pair this knowledge with the concepts covered in Big Data Analytics notes on the 3.0 University platform.
What is a Lambda Function in Python and When Should You Use It?
A lambda function in Python is written as lambda arguments: expression. It’s anonymous because you don’t give it a name with def. You can assign a python anonymous function to a variable if you want to reuse it, but most of the time you pass it directly into another function as an argument.
The canonical example is sorting a list of dictionaries. Say you have students with names and marks: students = [{"name": "Riya", "marks": 88}, {"name": "Dev", "marks": 95}]. To sort by marks you write sorted(students, key=lambda x: x["marks"]). No separate function needed. The lambda function in Python runs once per item, extracts the sort key and discards itself.
When Should You Use a Lambda Function Instead of def?
Use a lambda function in Python when the logic fits on one line and you only need it in one place. Use def when the function needs a name, multiple lines, documentation or reuse across your codebase. PEP 8, Python’s official style guide, explicitly says you should not assign a lambda function in Python to a variable name because that defeats the purpose of having def. That’s not an opinion, it’s the documented convention.
Lambda vs def: A Quick Comparison
| Feature | def Function | Lambda Function |
|---|---|---|
| Syntax length | Multi-line supported | Single expression only |
| Has a name | Yes | No (anonymous) |
| Supports statements | Yes | No |
| Best used for | Complex, reusable logic | Short, inline callbacks |
| Debuggability | Easier (named in tracebacks) | Harder (shows as lambda) |
| PEP 8 guidance | Preferred for named functions | Avoid assigning to a variable |
| Developer usage rate (JetBrains 2022) | ~100% of Python developers | Used regularly by 60%+ in web frameworks |
Where Lambda Functions Actually Appear in Real Code
You’ll spot a lambda function in Python inside map(), filter(), sorted() and GUI event handlers. Django and Flask developers use them in URL routing and query customisation. The Stack Overflow Developer Survey 2023 found Python ranked as the third most popular language globally, used by 49.28% of professional developers surveyed. That means lambda function in Python syntax is something you’ll encounter in codebases across industries whether you’re ready for it or not.
In India specifically, NASSCOM’s 2023 State of Technology report identified Python as the top language used in Indian IT services and product companies, with adoption growing fastest in Bengaluru, Hyderabad and Pune. If you’re planning to move into AI or machine learning work, you’ll use a lambda function in Python constantly inside pandas DataFrames with df.apply(lambda x: ...). The shift from data science to AI and ML guide on 3.0 University explains how Python skills like these directly map to real job requirements at companies like Infosys, TCS and Wipro.
Recursion, Generators and Decorators: Intermediate Python You Need
Once you’re comfortable with def and a lambda function in Python, three more function concepts unlock a lot of power: recursion, generators and decorators. They appear in real interview questions at companies across Bengaluru and Hyderabad, and in production code at startups throughout India.
What is Recursion in Python?
Recursion in Python means a function calls itself to solve a smaller version of the same problem. Every recursive function needs two things: a base case that stops the recursion and a recursive case that moves toward that base case. Without a base case, Python raises a RecursionError after hitting its default stack limit of 1,000 calls.
The classic example is factorial: def factorial(n): if n == 0: return 1 (base case) return n * factorial(n - 1) (recursive call). Call factorial(5) and Python computes 5 x 4 x 3 x 2 x 1 = 120 by unwinding the call stack. Recursion is elegant for tree traversal, directory scanning and divide-and-conquer algorithms. Use it where the logic naturally fits a recursive structure, not just to look clever.
What is a Generator in Python?
A generator in Python is a function that uses the python yield keyword instead of return. When you call a generator function, Python doesn’t execute it immediately. It returns a generator object. Each time you call next() on that object, execution resumes from where it left off and runs until the next yield.
The big difference is memory. A regular function that returns a list of one million numbers builds that entire list in RAM before handing it back. A generator produces one number at a time, using almost no memory regardless of how large the sequence is. According to the official Python documentation, generators are the right tool for reading large files, streaming data or infinite sequences. Python’s own range() function is implemented as a generator-like object in Python 3, which is why range(1000000) doesn’t crash your machine.
Example: def count_up(n): i = 0 then while i < n: yield i; i += 1. Call gen = count_up(1000000) and Python creates the generator instantly with no million integers in memory. Each next(gen) call computes and delivers one value. This pattern is extremely common in data engineering pipelines.
What are Python Decorators?
Python decorators are higher-order functions that wrap another function to extend or modify its behaviour. You apply them with the @decorator_name syntax placed on the line directly above a function definition. The original function’s source code stays untouched.
A practical example every developer should know is a timing decorator. You create a wrapper that records the time before and after calling the target function, then prints the difference. Apply @timer to any function and you get instant performance profiling with zero changes to the function itself. Django uses decorators heavily, including @login_required and @csrf_exempt. Flask uses @app.route() to map URLs to view functions.
The decorator function takes a function as its argument, defines an inner wrapper function that adds behaviour before and after calling the original, and returns that wrapper. The functools.wraps decorator from the standard library preserves the original function’s name and docstring inside the wrapper, which matters for debugging. According to the JetBrains Python Developers Survey 2022, decorators are used regularly by over 60% of Python developers who work with web frameworks.
If you want hands-on practice with these patterns in a structured environment, 3.0 University’s bootcamp training programs include Python fundamentals and applied programming projects designed for beginners and career switchers alike.
Generator vs Regular Function: When It Actually Matters
Use a generator when you’re working with large datasets, reading files line by line or building data pipelines. Use a regular function when you need the full result in memory at once, or when you’re returning a small, fixed collection. The yield keyword is your signal that memory efficiency is the priority.
You can connect with other learners working through exactly these concepts in the REACH learner community at 3.0 University, where students share code reviews, project feedback and study resources.
Frequently Asked Questions
What is a lambda function in Python?
A lambda function in Python is a small anonymous function written with the lambda keyword. It takes any number of arguments but only a single expression, which it evaluates and returns automatically. You don’t need a return statement. Lambda functions are most useful as inline arguments to functions like sorted(), map() and filter() where a full def block would be overkill.
When should you use a lambda function instead of def in Python?
Use a lambda function in Python when the logic is a single expression and you only need it in one place, typically as an inline callback. Use def when the function needs a name, multiple lines, a docstring or reuse across your codebase. PEP 8 explicitly advises against assigning a lambda function in Python to a variable name because that is exactly what def is for.
How do you define a function in Python?
You define a function using the def keyword, followed by the function name, parentheses containing any parameters and a colon. The function body is indented below. Use return to send a value back to the caller. If you omit return, the function returns None. You can use positional, keyword or default arguments depending on how flexible you need the function to be.
What is recursion in Python?
Recursion in Python is when a function calls itself to solve a progressively smaller version of a problem. Every recursive function must have a base case that stops the self-calling chain, and a recursive case that moves toward that base case. Python’s default recursion limit is 1,000 calls. Factorial and binary search are the most common beginner examples of recursive logic.
What are decorators in Python?
Decorators in Python are higher-order functions that wrap another function to add behaviour before or after it runs, without changing the original function’s code. You apply them using the @decorator_name syntax. Common real-world uses include logging, access control, input validation and performance timing. Django’s @login_required and Flask’s @app.route() are decorators you’ll use in almost every web project.
What is the difference between a generator and a function in Python?
A regular function runs completely and returns all its output at once. A generator uses the python yield keyword to pause execution and return one value at a time, resuming on the next call. This makes generators far more memory-efficient for large datasets. A function that returns a list of a million items stores all of them in RAM. A generator with the same data stores only one item at a time.
What is *args and **kwargs in Python?
*args lets a Python function accept any number of positional arguments, collecting them into a tuple. **kwargs does the same for keyword arguments, collecting them into a dictionary. Both are used to write flexible functions whose exact input isn’t known in advance. You’ll see this pattern in library APIs, decorators and any code designed to wrap or extend other functions.
Python’s function system goes much deeper than most beginners realise. The concepts here, from def and a lambda function in Python to recursion, generators and decorators, form the backbone of almost every serious Python project. Master these and you’re not just writing scripts, you’re writing code that other developers can read, extend and trust.
Your next steps this week: write a timing decorator from scratch, convert a list-returning function into a generator and sort a list of dictionaries using a lambda function in Python. Each one takes under ten minutes. If you want a structured path beyond these exercises, explore 3.0 University’s online certification courses in Cybersecurity, Ethical Hacking, Artificial Intelligence, Blockchain and Web3. The courses combine video instruction with hands-on labs and real-world projects so you build skills that actually show up on a resume. Check the 3.0 University blog for free tutorials, career guides and industry insights while you decide which path fits your goals.
Last updated: June 2025. Reviewed by the 3University editorial team.


