杰瑞科技汇

Python中range和xrange到底有啥区别?

Of course! This is a classic and very important topic in Python, especially for those who have worked with Python 2 or are concerned with performance and memory usage.

Python中range和xrange到底有啥区别?-图1
(图片来源网络,侵删)

Here’s a detailed breakdown of range and xrange.


The Short Answer (TL;DR)

  • In Python 3: There is only range. It is a smart, memory-efficient object that generates numbers on the fly when you iterate over it. It behaves like Python 2's xrange.
  • In Python 2: There were two types:
    • range: Created a full list of numbers in memory, which could be very memory-intensive for large ranges.
    • xrange: A memory-efficient object similar to Python 3's range. It's the one you should have used for large numbers.

If you are only using Python 3, you can forget about xrange entirely. Just use range.


Detailed Comparison

Let's break down the differences in a table and then explore the concepts in more detail.

Feature range (Python 3) xrange (Python 2)
Type A sequence type (specifically, an immutable sequence). A sequence type, but not a full list.
Memory Usage Low and Constant. It stores only the start, stop, and step values. Low and Constant. Same as Python 3's range.
Performance Excellent for iteration. Very fast because it doesn't pre-calculate values. Excellent for iteration. Same as Python 3's range.
List Creation list(range(10**6)) creates a real list with 1,000,000 elements in memory. range(10**6) creates the xrange object. list(xrange(10**6)) creates the full list.
Indexing/Slicing Supported. You can access elements by index (e.g., r[5]) or slice (e.g., r[1:10]). Supported. Same as Python 3's range.
Main Use Case The standard, preferred way to generate a sequence of numbers for loops and other purposes. The memory-efficient way to generate a sequence of numbers. The standard range was often avoided for large numbers.
Existence in Python 3 Does not exist. This is the most important point. Removed. Its functionality was merged into range.

range in Python 3 (The Modern Way)

In Python 3, range is a versatile and highly optimized object. It represents an immutable sequence of numbers and doesn't actually store all the numbers in memory.

Python中range和xrange到底有啥区别?-图2
(图片来源网络,侵删)

How it Works (Lazy Evaluation)

range is "lazy." It calculates the next number in the sequence only when it's needed (i.e., during a loop or when you ask for a specific element by index).

Example: Creating a range object

# This does NOT create a list of 1 million numbers in memory
r = range(1_000_000)
print(type(r))
# <class 'range'>
# You can check its properties, but it's tiny in memory
print(r)
# range(0, 1000000)
print(len(r))
# 1000000
# You can access elements by index (it calculates it on the fly)
print(r[500_000])
# 500000

Notice that range(1_000_000) is an object that takes up very little space, regardless of how large the range is.

Example: Using range in a Loop

This is the most common use case. The loop iterates over the range object, and one number at a time is generated and assigned to i.

Python中range和xrange到底有啥区别?-图3
(图片来源网络,侵删)
# This loop is very memory-efficient
total = 0
for i in range(1, 1_000_001):
    total += i
print(f"The sum of numbers from 1 to 1,000,000 is: {total}")
# The sum of numbers from 1 to 1,000,000 is: 500000500000

Example: Creating a List from a range

You can explicitly convert a range object into a list using the list() constructor. This is the only time the full list of numbers is created in memory.

# This WILL create a list of 10 elements in memory
small_list = list(range(10))
print(small_list)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# Be careful! This will consume a lot of memory
# large_list = list(range(10_000_000)) # Not recommended on machines with limited RAM

xrange in Python 2 (The Old Way)

In Python 2, the situation was different. The default range function was not memory-efficient.

range in Python 2

When you called range(1000), Python 2 would immediately create a list containing all 1000 integers.

# Python 2
r = range(10)
print(type(r))
# <type 'list'>
print(r)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# This would use a lot of memory for large ranges
# r = range(10000000) # Creates a list with 10 million integers!

This was fine for small ranges but could crash your program or consume all available memory for very large ranges.

xrange in Python 2 (The Solution)

xrange was introduced to solve this exact problem. It worked just like the modern range in Python 3.

  • It was a memory-efficient object.
  • It generated numbers on the fly.
  • It supported indexing and slicing.
# Python 2
xr = xrange(10)
print(type(xr))
# <type 'xrange'>
print(xr)
# xrange(10)
# It also supported indexing
print(xr[5])
# 5
# To get a list, you had to convert it
print(list(xr))
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Key Takeaways and Best Practices

  1. You are using Python 3. You only need to know about range. The xrange from Python 2 is gone.
  2. Use range for all your loops. It's fast, memory-efficient, and the standard way to do it.
    for i in range(10):
        print(i)
  3. Use list(range(...)) only when you explicitly need a list. If you need to perform list operations like multiple indexing, sorting, or passing to a function that requires a list, then convert it. But be mindful of the memory cost for very large ranges.
  4. Don't worry about performance for iteration. The lazy evaluation of range makes it extremely fast for for loops because it avoids the overhead of creating and managing a huge list in memory.
  5. Understand the difference between the object and the list. range(10) is an object. list(range(10)) is a list. This distinction is crucial for writing memory-efficient code.
分享:
扫描分享到社交APP
上一篇
下一篇