**lambda — anonymous functions**
A `lambda` is a single-expression anonymous function. It's not a stripped-down `def` — it's specifically for simple one-liners where naming the function adds no value:
```python
# def version:
def double(x):
return x * 2
# lambda version — exactly equivalent:
double = lambda x: x * 2
# lambda with two arguments:
add = lambda x, y: x + y
add(3, 4) # 7
# lambda with default:
greet = lambda name, greeting='Hello': f'{greeting}, {name}!'
greet('Alice') # 'Hello, Alice!'
greet('Bob', 'Hi') # 'Hi, Bob!'
```
Lambda is most useful as an inline argument — e.g. `key=lambda x: x[1]`.
**map() — transform every element**
```python
# map returns a map object — not a list!
result = map(str, [1, 2, 3]) # <map object at 0x...>
list(result) # ['1', '2', '3']
# With a lambda:
squares = list(map(lambda x: x ** 2, [1, 2, 3, 4]))
# [1, 4, 9, 16]
# map with two iterables:
sums = list(map(lambda a, b: a + b, [1, 2, 3], [10, 20, 30]))
# [11, 22, 33]
# map exhausts after first iteration — convert to list if you need to reuse:
m = map(str, range(5))
first = list(m) # ['0', '1', '2', '3', '4']
second = list(m) # [] — already exhausted!
```
**filter() — keep elements that match a predicate**
```python
# filter also returns an iterator — wrap in list() to see results
evens = list(filter(lambda x: x % 2 == 0, range(10)))
# [0, 2, 4, 6, 8]
# filter(None, ...) removes falsy values:
data = [0, 1, '', 'hello', None, True, [], [1]]
truthy = list(filter(None, data))
# [1, 'hello', True, [1]]
```
**functools.reduce() — fold a sequence into one value**
`reduce` is NOT a built-in in Python 3 — import it from `functools`:
```python
from functools import reduce
product = reduce(lambda acc, x: acc * x, [1, 2, 3, 4, 5])
# 120 (1*2*3*4*5)
# With initial value (avoids errors on empty sequences):
total = reduce(lambda acc, x: acc + x, [], 0) # 0 — safe, not error
```
lambda as key=, the operator module, and named functions vs lambda
**lambda as key= function**
The most common use of lambda in Python is as the `key=` argument for `sorted()`, `max()`, `min()`, `groupby()`, etc.:
```python
students = [('Alice', 85), ('Bob', 72), ('Carol', 91)]
# Sort by score (second element)
sorted(students, key=lambda s: s[1])
# [('Bob', 72), ('Alice', 85), ('Carol', 91)]
# Highest scorer
max(students, key=lambda s: s[1]) # ('Carol', 91)
# Sort strings case-insensitively
sorted(['Banana', 'apple', 'Cherry'], key=lambda s: s.lower())
# ['apple', 'Banana', 'Cherry']
```
**operator module — faster alternatives to lambda**
For the common cases of getting an item by index or an object attribute, the `operator` module provides optimised callables that run faster than lambda:
```python
import operator
# operator.itemgetter — same as lambda x: x[key]
sorted(students, key=operator.itemgetter(1)) # sort by index 1
# Works with multiple keys (returns tuple):
records = [('Alice', 'NY', 85), ('Bob', 'LA', 85), ('Carol', 'NY', 91)]
sorted(records, key=operator.itemgetter(2, 0)) # sort by score then name
# operator.attrgetter — same as lambda x: x.attr
from dataclasses import dataclass
@dataclass
class Student:
name: str
score: int
students = [Student('Alice', 85), Student('Bob', 72)]
sorted(students, key=operator.attrgetter('score'))
# operator.methodcaller — same as lambda x: x.method()
words = ['hello', 'WORLD', 'Python']
sorted(words, key=operator.methodcaller('lower'))
# ['hello', 'Python', 'WORLD']
```
**Named functions vs lambda — when each wins**
```python
# Lambda wins: short, inline, used once
sorted(data, key=lambda x: x['price'] * (1 - x['discount']))
# Named function wins: complex logic, reused, needs a docstring
def effective_price(item):
base = item['price']
discount = item.get('discount', 0)
tax = item.get('tax', 0.2)
return base * (1 - discount) * (1 + tax)
sorted(data, key=effective_price)
```
PEP 8 discourages assigning lambda to a variable name (`double = lambda x: x * 2`) — use `def` instead for clarity and tracebacks.
map/filter vs comprehensions, functools.partial, and decision guide
**map/filter vs comprehensions — readability comparison**
```python
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Double all even numbers — three ways:
# 1. map + filter (nested, reads inside-out):
result = list(map(lambda x: x * 2, filter(lambda x: x % 2 == 0, numbers)))
# 2. Comprehension (reads left to right, most Pythonic):
result = [x * 2 for x in numbers if x % 2 == 0]
# 3. For loop (most explicit):
result = []
for x in numbers:
if x % 2 == 0:
result.append(x * 2)
# All three produce: [4, 8, 12, 16, 20]
```
Comprehensions are the standard Python style for transformation + filtering.
**When map/filter still make sense**
```python
# map with a built-in (no lambda) — concise and fast:
names = list(map(str.upper, ['alice', 'bob', 'carol']))
# ['ALICE', 'BOB', 'CAROL']
# Same with a named function:
def to_celsius(f): return (f - 32) * 5 / 9
temps_c = list(map(to_celsius, [32, 68, 212]))
# [0.0, 20.0, 100.0]
# Piping through multiple operations (functional style):
pipeline = filter(None, map(str.strip, raw_lines))
```
**functools extras worth knowing**
```python
from functools import partial, lru_cache
# partial — create a specialised version of a function:
from functools import partial
double = partial(operator.mul, 2)
double(5) # 10
double(21) # 42
# lru_cache — memoize expensive functions:
@lru_cache(maxsize=128)
def fibonacci(n):
if n < 2: return n
return fibonacci(n - 1) + fibonacci(n - 2)
fibonacci(100) # instant, not exponential
```
**Quick decision guide**
```
Task Preferred style
────────────────────────────────── ─────────────────────────────────
Transform + filter a list List comprehension
Transform with a named/built-in fn map() without lambda
Filter only (no transform) filter() or comprehension
Fold/accumulate to one value reduce() or explicit loop
Inline sort key lambda or operator.itemgetter
Reusable key function def (named function)
```
Write a function that takes a list of prices and a discount percentage, and returns a new list with the discount applied to each price. Use map() with a lambda.
Write a function that takes a list of numbers and returns the largest sum you can reach by adding elements from left to right (i.e., the maximum value of any prefix sum). Use reduce() from functools.
from functools import reduce
def max_prefix_sum(numbers):
pass
result = max_prefix_sum([1, -3, 2, 5, -1, 3])
print(result)
Solution
from functools import reduce
def max_prefix_sum(numbers):
prefix_sums = []
reduce(lambda acc, n: (prefix_sums.append(acc + n) or (acc + n)), numbers, 0)
return max(prefix_sums)
# Or more clearly:
def max_prefix_sum(numbers):
total = 0
best = 0
for n in numbers:
total += n
best = max(best, total)
return best
result = max_prefix_sum([1, -3, 2, 5, -1, 3])
print(result)
No split tab
Cookie preferences
We use necessary cookies to run the site. With your permission, we can also save your site preferences and use analytics and advertising cookies to understand usage and support the project.
Open tools in tabs.Exercises, IDE tools, and trainers stay available as site tabs.
Switch without losing context.Move between explanations, code, and utilities while keeping your place.
Use the sidebar as your map.The left panels hold navigation, settings, files, libraries, and tool controls.
PythonJavaScriptSQLite
One IDE, three practical modes
Python in the browser.Run small scripts, try libraries, and practice API requests without installing anything.
JavaScript for quick experiments.Test browser-friendly code and compare ideas next to your learning materials.
SQLite for data practice.Open the database explorer to inspect tables, write queries, and learn SQL workflows locally.
TopicIDE
Work side by side with split tabs
Keep instructions visible.Open an exercise or reference page beside the IDE instead of jumping back and forth.
Compare tools while you learn.Place regex checks, explanations, and code experiments next to each other when the task needs it.
Close the split when you are done.The workspace returns to a single focused tab, and your open site tabs remain available.
Code Typing Trainer
Or plain text
This trainer is designed for a physical keyboard.Open this section on a laptop or desktop with a wide screen. Touch typing practice will not work correctly on a phone.
Speed: 0 chars/min
0 words/min
Best speed (60s): 0 chars/min
0 words/min
Errors: 0
Total time: 0.0 s
To practice touch typing, avoid looking at your physical keyboard.