Lambda, map, filter, and sorting
Anonymous functions and the functional built-ins used for sorting, ranking, and transforming records.
Why this matters in AI / ML / GenAI
Ranking retrieved chunks by score, sorting model results by latency, and applying a transform across a pandas column all use a `key=lambda` or a callable. It is the most common place a one-line function belongs.
1. Read
Understand the idea in plain English first.
2. Run
Load any example into the compiler and press Run.
3. Change
Edit one value, rerun, and learn from the output.
lambda
lambda args: expression creates a function without naming it. It holds a single expression — no statements, no loops, no assignments — and returns its value automatically.
add = lambda a, b: a + b works but is bad style. If it deserves a name, use def; PEP 8 says so explicitly, and def gives a useful name in tracebacks.
Lambda's real home is as an argument: sorted(items, key=lambda x: x["score"]).
sorted with key and reverse
sorted(iterable, key=..., reverse=...) returns a new list; list.sort(...) sorts in place and returns None.
The key function is applied to each element and the results are compared. Sorting dicts by a field, strings by length, or tuples by their second item are all one-liners.
Multi-level sort: return a tuple from key. key=lambda r: (-r["score"], r["id"]) sorts by score descending, then id ascending. Negating a number is the standard trick for mixing directions.
Python's sort is stable: equal keys keep their original order, so you can sort by one field, then another, and the earlier order survives inside ties.
operator.itemgetter("score") and attrgetter("score") are faster, clearer alternatives to lambda for simple field access.
map, filter, and reduce
map(fn, iterable) applies a function to each item. filter(fn, iterable) keeps items where the function is truthy. Both return lazy iterators — wrap in list() to see them.
In modern Python a comprehension is usually preferred: [f(x) for x in xs] reads better than list(map(f, xs)). Reach for map when the function already exists by name.
functools.reduce(fn, iterable, initial) folds a sequence into one value. Most uses are better served by sum, min, max, or math.prod — keep reduce for genuinely custom accumulation.
min and max also accept key, which is the cleanest way to pick the best-scoring record.
Hands-on practice
Compiler on the left. Examples on the right.
On desktop, keep the compiler beside the examples. On mobile, the same blocks stack cleanly. Pick an example, try it in the compiler, then change one small thing.
Build a model leaderboard
Live Python compiler
Try it — in-browser Python
Change the sort key to latency and see the ranking flip.
Code editor
Output
Python runs in your browser. First run downloads the runtime.
Press Run (or Ctrl+Enter) to execute.
Runs CPython in your browser. NumPy, pandas, scikit-learn and Matplotlib load on demand. Charts appear below the output. No input(), no GPU, no network installs.
Clear code examples
Every example is copy-ready. Use Try in compiler when you want to experiment without scrolling around.
Example
Ranking retrieved chunks
This is the reranking step of a RAG pipeline in one line.
chunks = [
{"id": "c1", "score": 0.71, "text": "python basics"},
{"id": "c3", "score": 0.94, "text": "rag pipelines"},
{"id": "c2", "score": 0.71, "text": "vector search"},
]
ranked = sorted(chunks, key=lambda c: c["score"], reverse=True)
for c in ranked:
print(f"{c['id']} {c['score']:.2f} {c['text']}")
print("\nbest:", max(chunks, key=lambda c: c["score"])["id"])
print("worst:", min(chunks, key=lambda c: c["score"])["id"])Example
Multi-level sort and stability
Tuple keys sort by several fields; negate a number to flip direction.
runs = [
{"model": "b", "score": 0.90, "latency": 300},
{"model": "a", "score": 0.90, "latency": 120},
{"model": "c", "score": 0.85, "latency": 100},
]
by_score_then_latency = sorted(runs, key=lambda r: (-r["score"], r["latency"]))
for r in by_score_then_latency:
print(f"{r['model']} score={r['score']:.2f} latency={r['latency']}")
from operator import itemgetter
print("\nitemgetter version:", [r["model"] for r in sorted(runs, key=itemgetter("latency"))])Example
map, filter, and comprehension side by side
Same result three ways — the comprehension is usually clearest.
scores = [0.91, 0.44, 0.78, 0.62, 0.95]
as_percent_map = list(map(lambda s: round(s * 100), scores))
as_percent_comp = [round(s * 100) for s in scores]
high_filter = list(filter(lambda s: s >= 0.7, scores))
high_comp = [s for s in scores if s >= 0.7]
print("map :", as_percent_map)
print("comprehension:", as_percent_comp)
print("filter :", high_filter)
print("comprehension:", high_comp)
print("map with a named function:", list(map(str.upper, ["mlops", "rag"])))Example
reduce and its better alternatives
Use reduce only when no built-in fits.
import functools
import math
tokens = [120, 340, 88, 502]
print("sum built-in :", sum(tokens))
print("reduce sum :", functools.reduce(lambda a, b: a + b, tokens))
print("math.prod :", math.prod([2, 3, 4]))
# A genuine reduce: merge a list of config dicts left to right.
configs = [{"lr": 1e-3}, {"epochs": 3}, {"lr": 2e-5, "fp16": True}]
merged = functools.reduce(lambda acc, d: {**acc, **d}, configs, {})
print("merged config:", merged)Takeaways
- lambda holds one expression and belongs inline as a key= argument.
- sorted(key=lambda r: (-r.score, r.id)) does multi-level sorting; Python's sort is stable.
- Prefer comprehensions over map/filter; use min/max with key to pick the best record.