NameError global name 'xrange' is not defined in Python 3
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
The error NameError: global name 'xrange' is not defined appears in Python 3 because xrange() was removed. The fix is usually simple: replace xrange(...) with range(...), because Python 3 range behaves like Python 2 xrange in the important ways that matter for iteration.
Why xrange Existed in Python 2
Python 2 had two similar built-ins:
- '
range()created a real list in memory' - '
xrange()produced numbers lazily as you iterated'
That meant xrange() was the better choice for large loops in Python 2:
Python 3 simplified this design by removing xrange() and making range() lazy and memory-efficient.
The Python 3 Fix
In Python 3, write:
That is the direct replacement in almost all migrated code.
You can also inspect the object:
This shows that range() is not pre-building the full list by default.
range in Python 3 Is Not the Old Python 2 range
This is the key migration insight. In Python 3:
- '
range()is iterable' - it is memory-efficient
- it supports indexing and slicing behavior similar to a sequence
So if your old Python 2 code used xrange() for performance, range() is now the intended replacement.
When You Actually Need a List
If the code truly needs a materialized list, convert explicitly:
This matters if:
- you need list methods such as
.append - a library expects a concrete list
- you want to serialize or print the full sequence as list data
Do not call list(range(...)) automatically unless the code really needs it, because that throws away the memory advantage.
Updating Old Compatibility Code
Sometimes older code tried to support both Python 2 and Python 3. A common migration cleanup is simply to remove xrange entirely and standardize on range.
For example, change:
to:
Or, even better, rewrite the loop more idiomatically:
Migration is a good chance to simplify code, not only to rename built-ins mechanically.
A Better Python 3 Style
Many loops that once used xrange do not need index-based iteration at all:
This is usually clearer than for i in range(len(items)) unless you specifically need index arithmetic.
Common Pitfalls
The biggest mistake is trying to define xrange = range everywhere as a long-term fix. That may patch the immediate error, but it keeps old Python 2 habits alive instead of moving the codebase cleanly to Python 3 style.
Another issue is assuming Python 3 range() returns a list and then trying to use list-only operations on it. If you need a list, convert it explicitly with list(range(...)).
Finally, do not rewrite every old xrange loop mechanically without reviewing the loop logic. Many of those loops can be improved with direct iteration or enumerate, which makes the migrated code more readable.
Summary
- '
xrange()does not exist in Python 3.' - Replace it with
range()in almost all migrated code. - Python 3
range()is lazy and memory-efficient like Python 2xrange(). - Use
list(range(...))only when you truly need a real list. - Treat the migration as a chance to modernize loop style, not just rename functions.
Related reading
- NameError name 'reduce' is not defined in Python
- NameError name 'self' is not defined
- Naming returned columns in Pandas aggregate function?
- Nearest Neighbors in Python given the distance matrix
- NameError uninitialized constant PaperclipStorageS3AWS
- Namespace stuck as Terminating. How do I remove it?
- Need To Compile Keras Model Before model.evaluate
- Negation in Python
.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 courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.