范围和 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 也支持切片,index 和 count:
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 版本之间的兼容性,你可以使用外部包 future 中的 builtins模块来实现向前兼容性和向后兼容性 : ** **
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 版本中的切片,index 和 count,就像 Python 3.2+中的内置方法一样。