显然xrange更快,但我不知道为什么它更快(除了目前为止的传闻之外,没有证据表明它更快),或者除此之外还有什么不同
for i in range(0, 20):
for i in xrange(0, 20):
显然xrange更快,但我不知道为什么它更快(除了目前为止的传闻之外,没有证据表明它更快),或者除此之外还有什么不同
for i in range(0, 20):
for i in xrange(0, 20):
当前回答
xrange只存储范围参数并根据需要生成数字。然而,Python的C实现目前将其args限制为C longs:
xrange(2**32-1, 2**32+1) # When long is 32 bits, OverflowError: Python int too large to convert to C long
range(2**32-1, 2**32+1) # OK --> [4294967295L, 4294967296L]
注意,在Python3.0中只有范围,它的行为类似于2.xxrange,但没有对最小和最大端点的限制。
其他回答
Python 2.x中的range()
该函数本质上是Python2.x中可用的旧range()函数,并返回包含指定范围内元素的列表对象的实例。
然而,当使用一系列数字初始化列表时,这种实现效率太低。例如,对于范围(1000000)中的i,无论是在内存还是时间使用方面,都是一个非常昂贵的命令,因为它需要将这个列表存储到内存中。
Python 3.x中的range()和Python 2.x中的xrange()
Python3.x引入了一个新的range()实现(而新的实现已经在Python2.x中通过xrange()函数提供)。
range()利用了一种称为惰性求值的策略。新的实现没有在范围内创建一个庞大的元素列表,而是引入了类范围,这是一个轻量级对象,表示给定范围内所需的元素,而没有将它们显式存储在内存中(这听起来可能像生成器,但惰性求值的概念不同)。
例如,考虑以下内容:
# Python 2.x
>>> a = range(10)
>>> type(a)
<type 'list'>
>>> b = xrange(10)
>>> type(b)
<type 'xrange'>
and
# Python 3.x
>>> a = range(10)
>>> type(a)
<class 'range'>
此外,if do list(xrange(…))将等同于range(…)。
所以列表很慢。
而且xrange确实没有完全完成序列
这就是为什么它不是一个列表,而是一个xrange对象
这是出于优化的原因。
range()将创建从开始到结束的值列表(示例中为0..20)。这将成为非常大范围的昂贵操作。
另一方面,xrange()更为优化。它只会在需要时(通过xrange序列对象)计算下一个值,不会像range()那样创建所有值的列表。
从帮助文档中。
Python 2.7.12
>>> print range.__doc__
range(stop) -> list of integers
range(start, stop[, step]) -> list of integers
Return a list containing an arithmetic progression of integers.
range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.
When step is given, it specifies the increment (or decrement).
For example, range(4) returns [0, 1, 2, 3]. The end point is omitted!
These are exactly the valid indices for a list of 4 elements.
>>> print xrange.__doc__
xrange(stop) -> xrange object
xrange(start, stop[, step]) -> xrange object
Like range(), but instead of returning a list, returns an object that
generates the numbers in the range on demand. For looping, this is
slightly faster than range() and more memory efficient.
Python 3.5.2
>>> print(range.__doc__)
range(stop) -> range object
range(start, stop[, step]) -> range object
Return an object that produces a sequence of integers from start (inclusive)
to stop (exclusive) by step. range(i, j) produces i, i+1, i+2, ..., j-1.
start defaults to 0, and stop is omitted! range(4) produces 0, 1, 2, 3.
These are exactly the valid indices for a list of 4 elements.
When step is given, it specifies the increment (or decrement).
>>> print(xrange.__doc__)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'xrange' is not defined
差异显而易见。在Python2.x中,range返回一个列表,xrange返回一个可迭代的xrange对象。
在Python3.x中,range变为Python2.x的xrange,xrange被删除。
xrange只存储范围参数并根据需要生成数字。然而,Python的C实现目前将其args限制为C longs:
xrange(2**32-1, 2**32+1) # When long is 32 bits, OverflowError: Python int too large to convert to C long
range(2**32-1, 2**32+1) # OK --> [4294967295L, 4294967296L]
注意,在Python3.0中只有范围,它的行为类似于2.xxrange,但没有对最小和最大端点的限制。