Python 2: range vs xrange

In Python 2, there were two functions:

  • range() — Created a list in memory
  • xrange() — Created an iterator (lazy evaluation, memory efficient)

Python 2: range()

# Python 2 only:
r = range(1000000)  # Creates a list with 1 million numbers in memory
print(type(r))      # 

This used a lot of memory for large ranges.

Python 2: xrange()

# Python 2 only:
x = xrange(1000000)  # Creates an iterator, doesn't store all numbers
print(type(x))       # <type 'xrange'>

# Only generates numbers when you iterate:
for i in x:
    print(i)  # Numbers generated one at a time

This was memory efficient, generating numbers on demand.

Python 3: range() only

In Python 3, xrange() was removed, and range() now works like the old xrange():

# Python 3:
r = range(1000000)  # Creates a range object (like old xrange)
print(type(r))      # 

# Memory efficient:
print(r[0])         # 0 (can still index)
print(r[999])      # 999
print(len(r))       # 1000000

# But doesn't store all numbers in memory
for i in r:
    print(i)  # Numbers generated on demand

What changed

Python 2 Python 3
range() — creates list range() — creates range object (memory efficient)
xrange() — creates iterator xrange() — removed (doesn't exist)

Today (Python 3)

Just use range() — it's always memory efficient:

# All of these work the same way (memory efficient):
for i in range(10):
    print(i)

for i in range(0, 10):
    print(i)

for i in range(0, 10, 2):  # Step by 2
    print(i)

# Can convert to list if needed:
numbers = list(range(10))  # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Benefits of Python 3 range()

  • Memory efficient: Doesn't create a list, generates numbers on demand
  • Still indexable: Can use range(10)[5] to get 5
  • Supports slicing: range(10)[2:5] works
  • Has length: len(range(10)) returns 10

If you need a list

If you specifically need a list (not just iteration), convert it:

# Create a list from range:
my_list = list(range(10))  # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# Or use list comprehension:
my_list = [i for i in range(10)]  # Same result

Summary

  • Python 2: Use xrange() for memory efficiency, range() if you need a list
  • Python 3: Just use range() — it's always memory efficient
  • If migrating: Replace xrange() with range() in Python 3 code