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 parallelfunc 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.