首页 文章

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

提问于
浏览
635

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

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

28 回答

  • 28

    range:-range将一次填充所有内容 . 这意味着范围的每个数字都将占用内存 .

    xrange:-xrange就像生成器一样,当你需要数字范围但是你不希望它们被存储时它会进入图片,就像你想要用于循环 . 内存效率高 .

  • 1

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

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

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

  • 5

    range创建一个列表,所以如果你做范围(1,10000000),它会在内存中创建一个包含9999999个元素的列表 . xrange是一个生成器,所以它是一个懒惰评估的序列对象 .

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

    list(range(1,100))
    
  • 10

    请记住,使用 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() 无论如何都会给你很好的迭代器行为 .

  • 2

    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 ,但没有最小和最大 endpoints 的限制 .

  • 0

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

  • 2

    花一些时间与Library Reference . 你对它越熟悉,你就能越快找到这样的问题的答案 . 关于内置对象和类型的前几章特别重要 .

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

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

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

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

    这为您带来两个好处:

    • 您可以在不获取 MemoryError 的情况下迭代更长的列表 .

    • 因为它会懒惰地解析每个数字,如果你提前停止迭代,你就不会浪费时间创建整个列表 .

  • 64

    我很震惊没有人读过doc

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

  • 12

    这是出于优化原因 .

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

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

  • 12

    在这个简单的例子中,您将发现 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中, range 功能的实现与Python-2中 xrange 的实现相同,而在Python-3中它们已经废弃 xrange

    快乐编码!!

  • 214

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

    xrange(): 与范围()相似,但相反返回列表,返回一个生成按需范围内的数字的对象 . 对于循环,这比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
    
  • 101

    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
    

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

  • 8

    在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)
    
  • 0

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

  • -1

    其他一些答案提到Python 3消除了2.x的 range 并将2.x的 xrange 重命名为 range . 但是,除非你're using 3.0 or 3.1 (which nobody should be), it'实际上是一个有点不同的类型 .

    正如the 3.1 docs所说:

    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)在2.6-2.7和3.0-3.1中返回True的事实是在3.2中修复但未向后移植的错误 .
  • 3

    python中的xrange()和range()与用户的工作方式类似,但是当我们讨论如何在使用该函数时分配内存时,差异就出现了 .

    当我们使用range()时,我们为它生成的所有变量分配内存,因此不建议使用较大的no . 要生成的变量 .

    另一方面,xrange()一次只生成一个特定的值,并且只能与for循环一起使用以打印所需的所有值 .

  • 37

    range生成整个列表并返回它 . xrange没有 - 它根据需要在列表中生成数字 .

  • 6

    阅读以下文章,了解范围和xrange之间的比较,并进行图形分析 .

    Python range Vs xrange

  • 4

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

  • 10

    什么?
    range 在运行时返回静态列表 .
    xrange 返回 object (其作用类似于生成器,但肯定不是一个),在需要时从中生成值 .

    什么时候用哪个?

    • 如果你想生成一个巨大范围的列表,比如10亿,请使用 xrange ,特别是当你有像手机这样的_1083546时 .

    • 如果要多次遍历列表,请使用 range .

    PS:Python 3.x的 range function == Python 2.x的 xrange 函数 .

  • 8

    在扫描/打印0-N项目的要求中,range和xrange的工作原理如下 .

    range() - 在内存中创建一个新列表,并将整个0到N个项目(完全为N 1)打印出来 . xrange() - 创建一个迭代器实例,它扫描项目并仅将当前遇到的项目保留在内存中,因此始终使用相同数量的内存 .

    如果所需元素有点位于列表的开头,那么它就会保存一个商品时间和记忆 .

  • 0

    对于 range(..) / 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% .

  • 722

    每个人都对此有很大的解释 . 但我希望它能为自己看到它 . 我用python3 . 所以,我打开资源监视器(在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()' .

  • 1

    Range 返回 list ,而 xrange 返回 xrange 对象,该对象占用相同的内存,与范围大小无关,因为在这种情况下,每次迭代只生成一个元素并且可用,而在使用范围的情况下,所有元素一次生成,在内存中可用 .

  • 0

    来自帮助文档 .

    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
    

    差异很明显 . 在Python 2.x中, range 返回一个列表, xrange 返回一个可迭代的xrange对象 .

    在Python 3.x中, range 变为Python 2.x的 xrangexrange 被删除 .

  • 5

    此外,如果 list(xrange(...)) 将等效于 range(...) .

    所以 list 很慢 .

    此外 xrange 确实没有完全完成序列

    所以's why its not a list, it'是一个 xrange 对象

  • 3

    看到这个post找到范围和xrange之间的区别:

    报价:

    range完全按照你的想法返回:一个连续整数的列表,定义长度以0. xrange开头,然而,返回一个“xrange对象”,它像迭代器一样运行很多

相关问题