Pythonrange和xrange函数之间的区别

示例

在Python 2中,range函数在xrange创建特殊xrange对象时返回一个列表,该对象是不可变序列,与其他内置序列类型不同,该对象不支持切片,并且既index没有count方法也没有方法:

Python 2.x 2.3
print(range(1, 10))
# 输出:[1、2、3、4、5、6、7、8、9]

print(isinstance(range(1, 10), list))
# 出:真

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

print(isinstance(xrange(1, 10), xrange))
# 出:真

在Python 3中,xrange已扩展为range序列,因此现在创建了一个range对象。没有xrange类型:

Python 3.x 3.0
print(range(1, 10))
# 出:范围(1,10)

print(isinstance(range(1, 10), range))
# 出:真

# 打印(xrange(1,10))
# 输出将是:
#追溯(最近一次通话):
#  File "<stdin>", line 1, in <module>
#NameError:名称“ xrange”未定义

另外,从Python 3.2开始,range还支持切片index和count:

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


使用特殊的序列类型而不是列表的优点是解释器不必为列表分配内存并填充它:

Python 2.x 2.3
# 范围(10000000000000000)
# 输出为:
# 追溯(最近一次通话):
#  File "<stdin>", line 1, in <module>
# MemoryError

print(xrange(100000000000000000))
# 出:xrange(100000000000000000)

由于通常需要后者的行为,因此在Python 3中已删除了前者。如果您仍然希望在Python 3中具有列表,则可以list()在range对象上简单地使用构造函数:

Python 3.x 3.0
print(list(range(1, 10)))
# 输出:[1、2、3、4、5、6、7、8、9]

兼容性

为了保持Python2.x和Python3.x版本之间的兼容性,您可以使用builtins外部包中的模块future来实现前向兼容后向兼容

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
frompast.builtinsimport xrange

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

将range在future库支持切片,index并count在所有的Python版本,就像内置了关于Python 3.2+方法。