显然xrange更快,但我不知道为什么它更快(除了目前为止的传闻之外,没有证据表明它更快),或者除此之外还有什么不同

for i in range(0, 20):
for i in xrange(0, 20):

当前回答

每个人都对它进行了大量的解释。但我想让它自己看。我用蟒蛇。因此,我打开了资源监视器(在Windows!中),首先执行了以下命令:

a=0
for i in range(1,100000):
    a=a+i

然后检查“正在使用”内存中的更改。这是微不足道的。然后,我运行了以下代码:

for i in list(range(1,100000)):
    a=a+i

它立即占用了大量内存。我确信。你可以自己试试。

如果您使用的是Python 2X,那么在第一段代码中,将“range()”替换为“xrange()”,将“list(range())”替换成“range()”。

其他回答

这是出于优化的原因。

range()将创建从开始到结束的值列表(示例中为0..20)。这将成为非常大范围的昂贵操作。

另一方面,xrange()更为优化。它只会在需要时(通过xrange序列对象)计算下一个值,不会像range()那样创建所有值的列表。

在这个简单的示例中,您将发现xrange优于range的优势:

import timeit

t1 = timeit.default_timer()
a = 0
for i in xrange(1, 100000000):
    pass
t2 = timeit.default_timer()

print "time taken: ", (t2-t1)  # 4.49153590202 seconds

t1 = timeit.default_timer()
a = 0
for i in range(1, 100000000):
    pass
t2 = timeit.default_timer()

print "time taken: ", (t2-t1)  # 7.04547905922 seconds

在xrange的情况下,上面的示例没有反映出任何明显更好的内容。

现在看看下面的例子,与xrange相比,range真的很慢。

import timeit

t1 = timeit.default_timer()
a = 0
for i in xrange(1, 100000000):
    if i == 10000:
        break
t2 = timeit.default_timer()

print "time taken: ", (t2-t1)  # 0.000764846801758 seconds

t1 = timeit.default_timer()
a = 0
for i in range(1, 100000000):
    if i == 10000:
        break
t2 = timeit.default_timer() 

print "time taken: ", (t2-t1)  # 2.78506207466 seconds

使用range,它已经创建了一个从0到100000000的列表(耗时),但xrange是一个生成器,它只根据需要生成数字,也就是说,如果迭代继续的话。

在Python-3中,范围功能的实现与Python-2中的xrange功能的实现相同,而他们在Python-3中取消了xrange

快乐编码!!

从帮助文档中。

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被删除。

range会创建一个列表,所以如果您选择range(10000000),它会在内存中创建一个包含9999999个元素的列表。xrange是一个生成器,因此它是一个序列对象。

这是正确的,但在Python3中,range()将由Python2xrange()实现。如果您需要实际生成列表,则需要执行以下操作:

list(range(1,100))

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'>