Question bank — Lambda functions — anonymous, used with map - filter
True or false — justify
Recall Reveal the True/False set
A lambda is a different kind of object from a function made with def. ::: False — both create the exact same type (a function object); type(lambda x: x) is <class 'function'>, identical to a def. The only real difference is the lambda has no meaningful __name__ (it's '<lambda>').
Every lambda can be rewritten as a def, and every def can be rewritten as a lambda. ::: Only half true — every lambda has a def equivalent, but a def with multiple statements (loops, assignments, several lines) has no lambda equivalent, because a lambda's body is a single expression.
map and filter return a list. ::: False — in Python 3 they return lazy iterator objects. You get a list only if you wrap them in list(...). Without it you see something like <map object at 0x...>.
A lambda always needs at least one argument. ::: False — lambda: 42 is a valid zero-argument lambda that returns 42 every time it is called with ().
Writing x = lambda n: n+1 is discouraged style, even though it works. ::: True — it works, but assigning a lambda to a name defeats its purpose; if you're naming it, a def is clearer and gives a proper name in tracebacks. PEP 8 explicitly recommends def here.
filter(None, items) is a syntax error because None is not a function. ::: False — passing None as the function is a special allowed case: filter(None, items) keeps every truthy element, exactly like filter(lambda x: x, items).
The lambda passed to map runs immediately when you call map(...). ::: False — because map is lazy, the lambda does not run until you consume the iterator (via list(), a for, next(), etc.). No consumption means the lambda never executes.
Spot the error
Recall Reveal the error-spotting set
lambda x: return x*x ::: SyntaxError — a lambda body must be a single expression, and return is a statement. The expression itself is the return value, so just write lambda x: x*x.
list(filter(lambda x: x*2, nums)) — meant to double the numbers. ::: Wrong tool — filter selects, it never transforms. x*2 is treated as a truthiness test, so this keeps every non-zero number unchanged. To double, use map: list(map(lambda x: x*2, nums)).
lambda x: y = x + 1 ::: SyntaxError — assignment (y = ...) is a statement, forbidden inside a lambda. A lambda holds one expression, not a block of code.
sorted(pairs, key=lambda a, b: a[1]) — sorting a list of pairs by second element. ::: Wrong signature — key receives one item at a time, so the lambda must take one argument: key=lambda p: p[1]. Two parameters causes a "missing argument" error at call time.
lambda x: if x > 0: 'pos' else: 'neg' ::: SyntaxError — an if: statement can't live in a lambda. Use the ternary expression: lambda x: 'pos' if x > 0 else 'neg'.
result = map(lambda x: x+1, [1,2,3]); print(list(result)); print(list(result)) — expecting the same list twice. ::: The second print shows [] — a map iterator is exhausted after one full pass. To reuse the data, store the first list(result) in a variable.
map(lambda x: print(x), nums) — expecting it to print each number. ::: Nothing prints — map is lazy and is never consumed here, so the lambda never runs. You'd need list(map(...)) or just a plain for loop (which is clearer for side-effects).
Why questions
Recall Reveal the "why" set
Why is a lambda called anonymous? ::: Because the expression lambda x: x*x produces a function object with no bound name of its own — it exists as a value you can pass around or use once, without ever being registered under an identifier.
Why can map, filter, and sorted accept a lambda as an argument at all? ::: Because functions in Python are first-class objects (see First-class functions) — a function can be stored, passed, and returned just like an integer or string. A lambda is simply such a value written inline.
Why does filter need a function that returns True/False rather than a number? ::: It doesn't strictly — it checks truthiness, so any value works; it keeps x when bool(f(x)) is True. A True/False predicate is just the clearest, most intentional form.
Why is a list comprehension often preferred over map/filter with a lambda? ::: A comprehension like [x*2 for x in nums] reads left-to-right in one line, avoids the list(...) wrapper, and skips the lambda call overhead (see List comprehensions). map/filter shine mainly when the function already exists by name.
Why are map and filter designed to be lazy instead of building a list right away? ::: Laziness (see Iterators and lazy evaluation) lets them process huge or infinite streams one element at a time, using near-constant memory, and lets you stop early without computing the whole sequence.
Why can't a lambda contain a loop or multiple statements? ::: By design a lambda is a compact expression, meant for tiny one-off rules. Real multi-step logic belongs in a named def where it's readable and testable — a deliberate readability boundary, not a technical accident.
Why does key=lambda p: p[1] change how sorted orders things? ::: sorted compares each item's key rather than the item itself (see sorted and key functions); by returning p[1] you tell it to compare using the second element, overriding the default tuple ordering that starts from p[0].
Edge cases
Recall Reveal the edge-case set
What does list(filter(lambda x: x, [0, '', None, 5, [], 'hi'])) return? ::: [5, 'hi'] — filter with an identity-like lambda keeps only truthy values, dropping 0, '', None, and the empty list [].
What does list(map(lambda x: x, [])) return? ::: [] — mapping over an empty iterable simply yields nothing; the lambda is never called. map/filter handle empty inputs gracefully.
What is the result of (lambda: 7)()? ::: 7 — a zero-argument lambda called with empty parentheses returns its constant expression. The trailing () is what actually invokes it.
If two lambdas have identical bodies, are they the same object? ::: No — (lambda x: x) is (lambda x: x) is False. Each lambda expression builds a fresh, distinct function object, even if the code text matches.
What happens with list(map(lambda x, y: x + y, [1,2,3], [10,20,30]))? ::: [11, 22, 33] — map can take multiple iterables and feeds one element from each into the multi-argument lambda in parallel. It stops at the shortest iterable if lengths differ.
In [lambda: i for i in range(3)], what do the three lambdas return when later called? ::: All return 2 — the lambdas capture the variable i (late binding), not its value at creation time; by the time they run, the loop has left i at its final value 2. This is the classic closure trap.
Does sorted([3, None, 1], key=lambda x: x) work? ::: No — it raises a TypeError because comparing None with an int is unsupported. The key function alone can't rescue values that are fundamentally uncomparable; you'd map them to a comparable proxy first.