map, filter & reduce Interview Questions & Answers
6 questions Updated 2026-06-18
Python interview questions on map laziness and multiple iterables, filter, functools.reduce, map/filter vs comprehensions, and consuming lazy iterators only once.
map(func, iterable) applies func to each item, returning a lazy iterator in
Python 3 — nothing is computed until you iterate it (or wrap it in list()). This
saves memory on large inputs because results are produced one at a time.
nums = [1, 2, 3]
result = map(lambda x: x * 2, nums)
print(result) # <map object ...> — not evaluated yet
print(list(result)) # [2, 4, 6] — now it runs
Because it's lazy, map never builds the full result in memory unless you ask for
it. In Python 2 map returned a list — a common gotcha when porting code.
Pass several iterables and map calls func with one item from each, in
parallel — func must accept that many arguments. It stops at the shortest
iterable, so mismatched lengths simply truncate.
a = [1, 2, 3]
b = [10, 20, 30]
list(map(lambda x, y: x + y, a, b)) # [11, 22, 33]
list(map(pow, [2, 3, 4], [10, 11])) # [1024, 177147] — stops at 2 items
This is handy for element-wise combining without an explicit zip. If you need the
longest length (padding the gaps), use itertools.zip_longest instead.
filter(predicate, iterable) keeps only the items for which predicate returns
truthy — also a lazy iterator in Python 3. As a special case, passing None as
the predicate keeps the items that are truthy themselves.
nums = [0, 1, 2, 0, 3]
list(filter(lambda x: x > 1, nums)) # [2, 3]
list(filter(None, nums)) # [1, 2, 3] — drops falsy values
Use it to drop elements by a condition. For complex conditions, a comprehension
with if is usually more readable than filter(lambda ...).
functools.reduce(func, iterable, initial) folds an iterable into a single
value by repeatedly applying a two-argument function, carrying an accumulator. In
Python 3 it was moved out of the builtins into functools — Guido considered it
less readable than an explicit loop, so it was demoted to discourage casual use.
from functools import reduce
reduce(lambda acc, x: acc + x, [1, 2, 3, 4], 0) # 10
# step by step: 0+1=1, 1+2=3, 3+3=6, 6+4=10
For common reductions, prefer the dedicated built-ins — sum, max, min,
math.prod, any, all — which are clearer and faster. Reach for reduce only
when no built-in expresses the fold.
A list/generator comprehension is the more Pythonic choice when you'd otherwise
write a lambda, because it's more readable and avoids the function-call overhead
per item. map/filter shine when you can pass an existing named function
(no lambda) and want a lazy iterator with minimal syntax.
nums = [1, 2, 3, 4]
[x * 2 for x in nums if x % 2] # comprehension — clearest with a condition
list(map(str, nums)) # map with a built-in — clean, no lambda
list(map(lambda x: x * 2, nums)) # lambda makes map less readable
Rule of thumb: if it needs a lambda, use a comprehension; if you're mapping an
already-named function, map reads fine. For laziness on huge data, a generator
expression (... for ...) gives both.
map/filter (and generators) are one-shot iterators: iterating them advances
an internal position that is never reset. Once exhausted, they yield nothing on a
second pass — a frequent source of "my second loop is empty" bugs.
doubled = map(lambda x: x * 2, [1, 2, 3])
list(doubled) # [2, 4, 6]
list(doubled) # [] — already consumed!
doubled = list(map(lambda x: x * 2, [1, 2, 3])) # materialize once
sum(doubled); max(doubled) # reuse freely
If you need to iterate more than once, convert to a list (or other concrete collection) up front. Use the lazy iterator directly only when a single pass is enough.
Practice tests are coming soon
Get notified when interactive mock interviews and quizzes launch.