NameError name 'reduce' is not defined in Python
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In Python 3, reduce() was moved from a built-in function to functools.reduce. Calling reduce() without importing it raises NameError: name 'reduce' is not defined. The fix is from functools import reduce. In Python 2, reduce was a built-in and required no import, which is why code ported from Python 2 often hits this error. The function applies a two-argument function cumulatively to a sequence, reducing it to a single value.
The Fix
In Python 2, this worked without any import:
Why Python 3 Moved reduce
Guido van Rossum argued that reduce() is rarely needed and often less readable than a simple loop. Python 3 removed it from built-ins to encourage clearer alternatives like sum(), math.prod(), any(), all(), and explicit loops. It was not removed entirely — it still lives in functools for cases where it genuinely simplifies code.
How reduce Works
Better Alternatives to reduce
For most common operations, Python provides clearer built-in alternatives:
When reduce Is Actually Useful
Python 2/3 Compatibility
Common Pitfalls
- Forgetting the import in Python 3: This is the most common cause. Code that worked in Python 2 breaks in Python 3. Add
from functools import reduceat the top of the file. Using a linter likeflake8catches undefined names before runtime. - Using reduce when a built-in exists:
reduce(lambda a, b: a + b, lst)is slower and harder to read thansum(lst). Similarly,reduce(operator.mul, ...)is less clear thanmath.prod(...)(Python 3.8+). Always check if a built-in covers your use case first. - Missing the initializer for empty sequences:
reduce(lambda a, b: a + b, [])raisesTypeError: reduce() of empty iterable with no initial value. Always provide an initializer when the input might be empty:reduce(func, items, default_value). - Assuming left-to-right associativity matters everywhere:
reducealways folds left-to-right. For operations like subtraction, this matters:reduce(lambda a, b: a - b, [10, 3, 2])gives(10 - 3) - 2 = 5, not10 - (3 - 2) = 9. For non-associative operations, verify the fold direction is what you intend. - Performance issues with string concatenation:
reduce(lambda a, b: a + b, strings)creates a new string on each step, giving O(n^2) performance. Use"".join(strings)for O(n) concatenation. The same applies to list concatenation — useitertools.chaininstead.
Summary
reducemoved tofunctools.reducein Python 3 — import it to fix the NameError- Use
sum(),math.prod(),max(),min(),any(),all(), andstr.join()instead ofreducewhen possible - Provide an initializer argument when the input sequence might be empty
reduceremains useful for function composition, deep data access, and custom accumulation patterns- For Python 2/3 compatibility, use a try/except import or the
sixlibrary

