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

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

当前回答

文件清楚地写道:

此函数与range()非常相似,但返回的是xrange对象而不是列表。这是一种不透明的序列类型,它产生与相应列表相同的值,而实际上没有同时存储所有值。xrange()相对于range()的优势很小(因为xrange)仍然需要在请求时创建值),除非在内存不足的机器上使用了非常大的范围,或者从未使用过范围的所有元素(例如,循环通常以break结束)。

其他回答

当在一个循环中测试range和xrange时(我知道我应该使用timeit,但这是使用一个简单的列表理解示例从内存中快速删除的),我发现如下:

import time

for x in range(1, 10):

    t = time.time()
    [v*10 for v in range(1, 10000)]
    print "range:  %.4f" % ((time.time()-t)*100)

    t = time.time()
    [v*10 for v in xrange(1, 10000)]
    print "xrange: %.4f" % ((time.time()-t)*100)

其给出:

$python range_tests.py
range:  0.4273
xrange: 0.3733
range:  0.3881
xrange: 0.3507
range:  0.3712
xrange: 0.3565
range:  0.4031
xrange: 0.3558
range:  0.3714
xrange: 0.3520
range:  0.3834
xrange: 0.3546
range:  0.3717
xrange: 0.3511
range:  0.3745
xrange: 0.3523
range:  0.3858
xrange: 0.3997 <- garbage collection?

或者,在for循环中使用xrange:

range:  0.4172
xrange: 0.3701
range:  0.3840
xrange: 0.3547
range:  0.3830
xrange: 0.3862 <- garbage collection?
range:  0.4019
xrange: 0.3532
range:  0.3738
xrange: 0.3726
range:  0.3762
xrange: 0.3533
range:  0.3710
xrange: 0.3509
range:  0.3738
xrange: 0.3512
range:  0.3703
xrange: 0.3509

我的代码段测试是否正确?对xrange的较慢实例有何评论?或者更好的例子:-)

range生成整个列表并返回它。xrange不——它根据需要生成列表中的数字。

这是出于优化的原因。

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

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

xrange使用迭代器(动态生成值),range返回一个列表。

其他一些答案提到Python 3消除了2.x的范围,并将2.x的xrange重命名为range。然而,除非您使用3.0或3.1(没有人应该使用),否则它实际上是一种不同的类型。

正如3.1文档所说:

范围对象的行为很少:它们只支持索引、迭代和len函数。

然而,在3.2+中,range是一个完整的序列,它支持扩展切片,以及collections.abc.sequence的所有方法,其语义与列表相同*

而且,至少在CPython和PyPy(目前仅有的两个3.2+实现)中,它还具有索引和计数方法以及in运算符的常量时间实现(只要只传递整数)。这意味着在r中写123456在3.2+中是合理的,而在2.7或3.1中则是一个糟糕的想法。


*issubclass(xrange,collections.Sequence)在2.6-2.7和3.0-3.1中返回True的事实是一个在3.2中修复的错误,而不是后端口。