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

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

当前回答

一定要花一些时间阅读图书馆参考资料。你越熟悉它,就越能更快地找到类似问题的答案。特别重要的是关于内置对象和类型的前几章。

xrange类型的优点是xrange对象总是使用相同数量的内存,无论它代表的范围大小如何。没有一致的性能优势。

另一种快速查找Python构造信息的方法是docstring和help函数:

print xrange.__doc__ # def doc(x): print x.__doc__ is super useful
help(xrange)

其他回答

当在一个循环中测试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(x,y)返回x和y之间的每个数字的列表,如果使用for循环,则range会变慢。事实上,范围的指数范围更大。range(x.y)将打印出x和y之间所有数字的列表

xrange(x,y)返回xrange,但如果使用for循环,xrange会更快。xrange的索引范围较小。xrange不仅会打印出xrange(x,y),还会保留其中的所有数字。

[In] range(1,10)
[Out] [1, 2, 3, 4, 5, 6, 7, 8, 9]
[In] xrange(1,10)
[Out] xrange(1,10)

如果您使用for循环,那么它会起作用

[In] for i in range(1,10):
        print i
[Out] 1
      2
      3
      4
      5
      6
      7
      8
      9
[In] for i in xrange(1,10):
         print i
[Out] 1
      2
      3
      4
      5
      6
      7
      8
      9

使用循环时没有太大的区别,但打印循环时有区别!

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

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

list(range(1,100))

其他一些答案提到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中修复的错误,而不是后端口。

对于范围(..)/xrange(..)的较小参数,差异减小:

$ python -m timeit "for i in xrange(10111):" " for k in range(100):" "  pass"
10 loops, best of 3: 59.4 msec per loop

$ python -m timeit "for i in xrange(10111):" " for k in xrange(100):" "  pass"
10 loops, best of 3: 46.9 msec per loop

在这种情况下,xrange(100)的效率仅提高约20%。