範圍和 xrange 函式之間的差異

在 Python 2 中, range 函式返回一個列表,而 xrange 建立一個特殊的 xrange 物件,這是一個不可變序列,與其他內建序列型別不同,它不支援切片,既沒有 index 也沒有 count 方法:

Python 2.x >= 2.3

print(range(1, 10))
# Out: [1, 2, 3, 4, 5, 6, 7, 8, 9]

print(isinstance(range(1, 10), list))
# Out: True

print(xrange(1, 10))
# Out: xrange(1, 10)

print(isinstance(xrange(1, 10), xrange))
# Out: True

在 Python 3 中,xrange 被擴充套件為 range 序列,因此現在建立了一個 range 物件。沒有 xrange 型別:

Python 3.x >= 3.0

print(range(1, 10))
# Out: range(1, 10)

print(isinstance(range(1, 10), range))
# Out: True

# print(xrange(1, 10))
# The output will be:
#Traceback (most recent call last):
#  File "<stdin>", line 1, in <module>
#NameError: name 'xrange' is not defined

另外,從 Python 3.2 開始,range 也支援切片,indexcount

print(range(1, 10)[3:7])
# Out: range(3, 7)
print(range(1, 10).count(5))
# Out: 1
print(range(1, 10).index(7))
# Out: 6

使用特殊序列型別而不是列表的優點是直譯器不必為列表分配記憶體並填充它:

Python 2.x >= 2.3

# range(10000000000000000)
# The output would be:
# Traceback (most recent call last):
#  File "<stdin>", line 1, in <module>
# MemoryError

print(xrange(100000000000000000))
# Out: xrange(100000000000000000)

由於通常需要後一種行為,因此在 Python 3 中刪除了前者。如果你仍想在 Python 3 中使用列表,則只需在 range 物件上使用 list() 建構函式:

Python 3.x >= 3.0

print(list(range(1, 10)))
# Out: [1, 2, 3, 4, 5, 6, 7, 8, 9]

相容性

為了保持 Python 2.x 和 Python 3.x 版本之間的相容性,你可以使用外部包 futurebuiltins模組來實現向前相容性向後相容性 ** **

Python 2.x >= 2.0

#forward-compatible
from builtins import range

for i in range(10**8):
    pass

Python 3.x >= 3.0

#backward-compatible
from past.builtins import xrange

for i in xrange(10**8):
    pass

future 庫中的 range 支援所有 Python 版本中的切片,indexcount,就像 Python 3.2+中的內建方法一樣。