NameError name 'reduce' is not defined in Python
Data Structures & Algorithms practice on Codemia
Step through 300+ coding interview problems with animated visualisers that show the data structure changing as the code runs. The Blind 75 are free.
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
Related reading
- NameError name 'self' is not defined
- Naming returned columns in Pandas aggregate function?
- Nearest Neighbors in Python given the distance matrix
- Need To Compile Keras Model Before model.evaluate
- NameError uninitialized constant PaperclipStorageS3AWS
- Namespace stuck as Terminating. How do I remove it?
- Negation in Python
- Negative dimension size caused by subtracting 3 from 1 for 'Conv2D
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseNo course covers this one yet
Basis Lab writes one for you from a sentence about what you want to be able to do, then teaches it and checks you understood. Your first course is free.
Build my courseData Structures & Algorithms practice on Codemia
Step through 300+ coding interview problems with animated visualisers that show the data structure changing as the code runs. The Blind 75 are free.