What is the difference between range and xrange functions in Python 2.X?
显然xrange更快,但我不知道为什么它更快(除了目前为止的轶事,没有证据证明它更快),或者除此之外还有什么不同的地方
1 2 | for i in range(0, 20): for i in xrange(0, 20): |
range创建一个列表,所以如果您执行
应该从@thiago的提示中添加,在python3中,range的作用相当于python的xrange
range creates a list, so if you do
range(1, 10000000) it creates a list in memory with9999999 elements.
xrange is a generator, so itis a sequence objectis athat evaluates lazily.
这是正确的,但是在python 3中,
1 | list(range(1,100)) |
记住,使用
1 2 3 4 | $ 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 |
就我个人而言,我总是使用
1 2 | 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中,只有
xrange返回一个迭代器,一次只在内存中保留一个数字。range将整个数字列表保存在内存中。
一定要花些时间参考图书馆。你对它越熟悉,你就越能更快地找到这样的问题的答案。特别重要的是关于内置对象和类型的前几章。
The advantage of the xrange type is that an xrange object will always
take the same amount of memory, no matter the size of the range it represents.
There are no consistent performance advantages.
另一种查找有关python结构的快速信息的方法是docstring和帮助函数:
1 2 | print xrange.__doc__ # def doc(x): print x.__doc__ is super useful help(xrange) |
我很震惊没人看医生:
This function is very similar to
range() , but returns anxrange object instead of a list. This is an opaque sequence type which yields the same values as the corresponding list, without actually storing them all simultaneously. The advantage ofxrange() overrange() is minimal (sincexrange() still has to create the values when asked for them) except when a very large range is used on a memory-starved machine or when all of the range’s elements are never used (such as when the loop is usually terminated withbreak ).
range creates a list, so if you do range(1, 10000000) it creates a list in memory with 10000000 elements.
xrange is a generator, so it evaluates lazily.
这给您带来了两个优势:
在这个简单的例子中,您会发现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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 |
上面的例子并没有反映出在
现在看看下面的情况,与
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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 |
使用
在python-3中,
快乐编码!!
这是出于优化的原因。
range()将创建从开始到结束的值列表(0..20)。这将成为一个非常大范围的昂贵操作。
另一方面,xrange()更加优化。它只在需要时计算下一个值(通过xrange sequence对象),不会像range()那样创建所有值的列表。
1 2 3 4 | [In] range(1,10) [Out] [1, 2, 3, 4, 5, 6, 7, 8, 9] [In] xrange(1,10) [Out] xrange(1,10) |
如果您使用一个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | [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(1,10)返回从1到10个数字的列表,并将整个列表保存在内存中。
xrange():与range()类似,但不返回列表,而是返回一个按需生成范围中数字的对象。对于循环,这比range()稍快,内存效率更高。xrange()类似于迭代器的对象,并根据需要生成数字。(lazy evaluation)
1 2 3 4 5 6 7 8 9 10 11 | 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 |
在Python 2。
range(x)返回在内存中用x元素创建的列表。
1 2 3 | >>> a = range(5) >>> a [0, 1, 2, 3, 4] |
xrange(x)返回一个xrange对象,它是一个按需生成数字的生成器对象。它们是在for循环(延迟计算)期间计算的。
对于循环,这比range()稍快,内存效率更高。
1 2 3 | >>> b = xrange(5) >>> b xrange(5) |
其他一些答案提到,python 3删除了2.x的
如3.1文件所述:
Range objects have very little behavior: they only support indexing, iteration, and the
len function.
但是,在3.2+中,
而且,至少在cpython和pypy(目前仅有的两个3.2+实现)中,它还具有
*事实上,
当在循环中对xrange测试范围时(我知道我应该使用timeit,但这是使用一个简单的列表理解示例从内存中快速破解出来的),我发现了以下内容:
1 2 3 4 5 6 7 8 9 10 11 | 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) |
它给出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | $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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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实例有何评论?或者一个更好的例子:—)
python中的xrange()和range()的工作方式与用户的工作方式类似,但当我们讨论如何使用这两个函数来分配内存时,就会有不同。
当我们使用range()时,我们为它正在生成的所有变量分配内存,因此不建议在生成的变量数量较大时使用。
另一方面,xrange()一次只能生成一个特定的值,并且只能与for循环一起用于打印所需的所有值。
阅读以下文章,了解用图形分析比较range和xrange。
python范围与xrange
range生成整个列表并返回它。xrange不——它根据需要生成列表中的数字。
xrange使用迭代器(动态生成值),range返回一个列表。
什么?
何时使用哪个?
- 如果你想生成一个大范围的列表,比如10亿,尤其是当你有一个像手机这样的"记忆敏感系统"时,使用EDOCX1[1]。
- 如果您想对列表进行多次迭代,请使用
range 。
ps:python 3.x的
小参数的
1 2 3 4 5 | $ 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 |
在这种情况下,
大家都解释得很清楚。但我想亲自去看看。我使用Python 3。所以,我打开了资源监视器(在Windows中!),首先,首先执行以下命令:
1 2 3 | a=0 for i in range(1,100000): a=a+i |
然后检查"使用中"内存的变化。这是微不足道的。然后,我运行了以下代码:
1 2 | for i in list(range(1,100000)): a=a+i |
它立刻占用了大量的内存。我深信不疑。你可以自己试试。
如果您使用的是python 2X,那么在第一个代码中将"range()"替换为"xrange()",将"list(range())"替换为"range()"。
对于扫描/打印0-n项的要求,range和xrange的工作方式如下。
range()-在内存中创建一个新列表,并获取整个0到n个项目(总共n+1)并打印它们。xrange()-创建一个迭代器实例,该实例扫描所有项,只将当前遇到的项保存到内存中,因此始终使用相同的内存量。
如果所需元素只是在列表的开头,那么它可以节省大量的时间和内存。
此外,如果是,
所以
另外,
这就是为什么它不是一个列表,它是一个
range返回一个列表,而xrange返回一个xrange对象,该对象占用相同的内存,与范围大小无关,在这种情况下,每次迭代只生成一个元素并可用,而在使用range的情况下,所有元素都会同时生成并在内存中可用。
range:-range将一次填充所有内容。这意味着range中的每个数字都将占用内存。
xrange:-xrange类似于generator,当你想要数字的范围,但你不希望它们被存储时,它就会出现在图片中,就像你想在for循环中使用时一样。这样内存效率很高。
来自帮助文档。
Python 2.7.12
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | >>> 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | >>> 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中,
在python 3.x中,
请参阅本帖了解range和xrange之间的区别:
引述:
range returns exactly what you think: a list of consecutive
integers, of a defined length beginning with 0.xrange , however,
returns an"xrange object", which acts a great deal like an iterator