当前位置:  开发笔记 > 编程语言 > 正文

Python 2.X中range和xrange函数有什么区别?

如何解决《Python2.X中range和xrange函数有什么区别?》经验,为你挑选了15个好方法。

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

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

小智.. 782

range创建一个列表,所以如果你这样做range,就会在内存中用range(1, 10000000)元素创建一个列表.

9999999 是一个懒惰评估的序列对象.

它应该从@Thiago的提示中添加,在python3中,范围相当于python的xrange



1> 小智..:

range创建一个列表,所以如果你这样做range,就会在内存中用range(1, 10000000)元素创建一个列表.

9999999 是一个懒惰评估的序列对象.

它应该从@Thiago的提示中添加,在python3中,范围相当于python的xrange


xrange是nto完全是一个生成器,但它懒惰地评估并且像一个生成器.
`xrange(x).__ iter __()`是一个生成器.
他们为什么要做xrange,而不是让范围懒惰?
@RobertGrant,他们做到了.在Python 3中(他们无法在Python 2.x系列中执行此操作,因为所有更改都必须向后兼容.)
@Ratul意味着每个`i`都是按需评估而不是初始化.
有人可以解释一下"懒惰评估"是什么意思吗?谢谢!
请注意,这仅适用于Python2.由于Python3没有"xrange",因此它的"range"函数将像Python2的xrange一样工作.
@RobertGrant如果你遍历该列表1000次,每次生成值都会慢一些

2> Corey..:

range创建一个列表,所以如果你这样做range(1, 10000000),就会在内存中用9999999元素创建一个列表.

xrange 为发电机,所以它是一个序列对象是一个计算结果懒惰地.

这是事实,但在Python 3中,.range()将由Python 2实现.xrange().如果您需要实际生成列表,则需要执行以下操作:

list(range(1,100))


+1感谢您的回答,有关使用xrange替换范围的Python 3的信息非常有用.我实际上告诉别人使用xrange代替或范围,他们说在python 3中没关系,所以我谷歌搜索更多信息,这个答案出现了:)
我没有看到这是一个巨大的问题(关于打破现有的应用程序),因为范围主要是为了生成用于for循环的索引"for i in range(1,10):"

3> John Fouhy..:

请记住,使用该timeit模块来测试哪些代码的小片段更快!

$ python -m timeit 'for i in range(1000000):' ' pass'
10 loops, best of 3: 90.5 msec per loop
$ python -m timeit 'for i in xrange(1000000):' ' pass'
10 loops, best of 3: 51.1 msec per loop

就个人而言,我总是使用.range(),除非我正在处理真正庞大的列表 - 正如你所看到的,时间方面,对于一百万个条目的列表,额外的开销只有0.04秒.正如Corey指出的那样,Python 3.0 .xrange()将会消失,.range()无论如何都会给你很好的迭代器行为.


+1为timeit示例.注意:要在windows cmd中运行,需要使用双引号,即".所以代码将是`python -m timeit"for x in xrange(1000000):""pass"`
xrange的主要好处是记忆,而不是时间.
我一般同意你的陈述,但是你的评价是错误的:`额外的开销只有0.04秒`不是正确看待它的方式,`(90.5-51.1)/51.1 = 1.771倍慢'是正确的,因为它传达了如果这是你的程序的核心循环,它可能会成为瓶颈.但是,如果这只是一小部分,那么1.77倍并不多.
如果xrange更快并且不会占用内存,为什么要使用范围?
+1为实际答案:**使用范围,除非巨大的**.顺便说一下,它们在概念上是相同的,对吗?奇怪的是没有答案说出来.
这是个坏建议。实际上,“范围”的唯一缺点是,如果您对它的阅读不如“ xrange”那么丑陋,或者您确实需要“列表”,则可能会觉得美观。此外,在计算机上运行timeit可能与运行代码的环境不太相似,也无济于事。

4> efotinis..:

xrange只存储范围参数并按需生成数字.但是,Python的C实现目前将其args限制为C long:

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]

请注意,在Python 3.0中只有range它,它的行为类似于2.x,xrange但没有最小和最大端点的限制.



5> Ben Hoffstei..:

xrange返回一个迭代器,一次只在内存中保留一个数字.range将整个数字列表保存在内存中.


`xrange`确实_not_返回迭代器.
@SIslam如果它知道开始,结束和当前,它可以一次计算下一个,一个.

6> Antti Rasine..:

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

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

查找有关Python构造的快速信息的另一种方法是docstring和help-function:

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


转到库参考,点击ctrl + f,搜索范围,你会得到两个结果.找到这个问题的答案并不是很费力.

7> Lucas S...:

range创建一个列表,因此如果你执行range(1,10000000),它会在内存中创建一个包含10000000个元素的列表.xrange是一个生成器,所以它懒惰地评估.

这为您带来两个好处:

    您可以迭代更长的列表而无需获取MemoryError.

    由于它可以懒散地解析每个数字,如果您提前停止迭代,则不会浪费时间创建整个列表.



8> Kishor Pawar..:

我很震惊没有人读过doc:

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



9> QAZ..:

这是出于优化原因.

range()将从头到尾创建一个值列表(在您的示例中为0 .. 20).这将在非常大的范围内成为昂贵的操作.

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



10> User_Targary..:

你会发现的优势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.

现在看看以下情况,range与之相比真的很慢xrange.

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中,range功能的实现与Python-2中的实现相同xrange,而它们xrange在Python-3中已经废弃了

快乐编码!!



11> Supercolbat..:

range(x,y)如果使用for循环,则返回x和y之间的每个数字的列表,然后range更慢.事实上,range指数范围更大.range(x.y)将打印出x和y之间所有数字的列表

xrange(x,y)返回,xrange(x,y)但如果你使用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

使用循环时没有太大区别,虽然只是打印时有区别!



12> Tushar.PUCSD..:

range(): range(1,10)返回1到10个数字的列表,并将整个列表保存在内存中.

xrange():与range()类似,但不返回列表,而是返回一个对象,该对象根据需要生成范围内的数字.对于循环,这比range()和内存效率更快.xrange()对象就像一个迭代器,并根据需要生成数字.(懒惰评估)

In [1]: range(1,10)

Out[1]: [1, 2, 3, 4, 5, 6, 7, 8, 9]

In [2]: xrange(10)

Out[2]: xrange(10)

In [3]: print xrange.__doc__

xrange([start,] stop[, step]) -> xrange object



13> Siyaram Mala..:

在python 2.x中

range(x)返回一个列表,该列表在内存中使用x元素创建.

>>> a = range(5)
>>> a
[0, 1, 2, 3, 4]

xrange(x)返回一个xrange对象,它是一个生成器obj,它根据需要生成数字.它们是在for-loop期间计算的(延迟评估).

对于循环,这比range()稍快,内存效率更高.

>>> b = xrange(5)
>>> b
xrange(5)



14> Dave Everitt..:

当在循环中测试范围对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较慢的实例有何评论?或者更好的例子:-)


像这样运行一次基准测试,不会提供准确的计时结果.总是存在差异..它可能是GC,或者其他进程窃取CPU ......任何事情.这就是为什么基准测试通常运行10-100-1000 -...
这就是`timeit`的用途.它需要多次运行,禁用GC,使用最佳时钟而不是"时间"等.

15> abarnert..:

一些其他的答案中提到的Python 3淘汰2.X的range,并更名为2.X的xrangerange.但是,除非你使用3.0或3.1(没有人应该),否则它实际上是一种不同的类型.

正如3.1文档所说:

Range对象的行为很少:它们只支持索引,迭代和len函数.

但是,在3.2+中,range是一个完整的序列 - 它支持扩展切片,并且所有方法都collections.abc.Sequence具有相同的语义list.*

而且,至少在CPython和PyPy(目前只存在两个3.2+实现)中,它还具有indexcount方法和in运算符的常量实现(只要你只传递整数).这意味着写作123456 in r在3.2+中是合理的,而在2.7或3.1中则是一个可怕的想法.


*一个事实,issubclass(xrange, collections.Sequence)返回True在2.6-2.7 3.0-3.1和是一个错误是固定在3.2,而不是向后移植.

推荐阅读
围脖上的博博_771
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有