python中的xrange()和range()与用户的工作方式类似,但是当我们讨论如何在使用该函数时分配内存时,差异就出现了。
当我们使用range()时,我们为它生成的所有变量分配内存,因此不建议使用较大的no。要生成的变量。
另一方面,xrange()一次只生成一个特定的值,并且只能与for循环一起使用以打印所需的所有值。
range:-range将一次填充所有内容。这意味着范围的每个数字都将占用内存。
xrange:-xrange就像生成器一样,当你需要数字范围但是你不希望它们被存储时它会进入图片,就像你想要用于循环。内存效率高。
的 范围(): 强> 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
阅读以下文章,了解范围和xrange之间的比较,并进行图形分析。
Python范围与xs xrange
的 范围 强> 返回一个 的 名单 强> 而 的 的xrange 强> 返回一个 的 的xrange 强> 无论范围大小如何都占用相同存储器的对象,在这种情况下,每次迭代仅生成一个元素并且可用,而在使用范围的情况下,所有元素一次生成并且在存储器中可用。
xrange使用迭代器(动态生成值),range返回一个列表。
来自帮助文档。
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对象。
range
xrange
在Python 3.x中, range 变 xrange Python 2.x和 xrange 已移除。
另外,如果这样做 list(xrange(...)) 将等同于 range(...) 。
list(xrange(...))
range(...)
所以 list 是慢的。
list
也 xrange 真的没有完全完成序列
所以这就是为什么它不是一个列表,它是一个 xrange 宾语
range生成整个列表并返回它。 xrange没有 - 它根据需要在列表中生成数字。
每个人都对此有很大的解释。但我希望它能为自己看到它。我用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()'。
范围创建一个列表,所以如果你这样做 range(1, 10000000) 它在内存中创建一个列表 9999999 元素。
range(1, 10000000)
9999999
xrange 是一个懒惰评估的序列对象。
它应该从@Thiago的提示中添加,在python3中,范围相当于python的xrange
在循环中测试范围对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(..)
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%。
xrange(100)
在python 2.x中
的 范围(x)的 强> 返回一个列表,该列表在内存中使用x元素创建。
>>> a = range(5) >>> a [0, 1, 2, 3, 4]
的 的xrange(x)的 强> 返回一个xrange对象,它是一个生成器obj,它根据需要生成数字。它们是在for-loop期间计算的(延迟评估)。
对于循环,这比range()稍快,内存效率更高。
>>> b = xrange(5) >>> b xrange(5)
xrange返回一个迭代器,一次只在内存中保留一个数字。 range将整个数字列表保存在内存中。
看到这个 岗位 找到范围和xrange之间的差异:
报价:
range 完全按照你的想法返回:一个连续的列表 整数,定义长度从0开始。 xrange 然而, 返回一个 “xrange对象” ,它像迭代器一样发挥很大作用
其他一些答案提到Python 3消除了2.x的 range 并重命名为2.x's xrange 至 range 。但是,除非你使用3.0或3.1(没有人应该这样),否则它实际上是一种不同的类型。
如 3.1文档 说:
Range对象的行为非常少:它们只支持索引,迭代和 len 功能。
len
但是,在3.2+中, range 是一个完整序列 - 支持扩展切片,以及所有方法 collections.abc.Sequence 与...相同的语义 list 。 *
collections.abc.Sequence
并且,至少在CPython和PyPy(目前仅存在的两个3.2+实现)中,它还具有的常量实现 index 和 count 方法和 in 运算符(只要你只传递整数)。这意味着写作 123456 in r 在3.2+中是合理的,而在2.7或3.1中则是一个可怕的想法。
index
count
in
123456 in r
<子> *事实 issubclass(xrange, collections.Sequence) 回报 True 在2.6-2.7和3.0-3.1是 一个bug 在3.2中修复但未向后移植。 子>
issubclass(xrange, collections.Sequence)
True
这是出于优化原因。
range()将从头到尾创建一个值列表(在您的示例中为0 .. 20)。这将在非常大的范围内成为昂贵的操作。
另一方面,xrange()更加优化。它只会在需要时(通过xrange序列对象)计算下一个值,并且不会创建像range()那样的所有值的列表。
在扫描/打印0-N项目的要求中,range和xrange的工作原理如下。
range() - 在内存中创建一个新列表,并将整个0到N个项目(总共N + 1)并打印出来。 xrange() - 创建一个迭代器实例,它扫描项目并仅将当前遇到的项目保留在内存中,因此始终使用相同数量的内存。
如果所需元素稍微位于列表的开头,那么它将节省大量时间和内存。
记住,使用 timeit 用于测试哪些代码片段更快的模块!
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() 无论如何都会给你很好的迭代器行为。
.range()
.xrange()
range创建一个列表,因此如果你执行range(1,10000000),它会在内存中创建一个包含10000000个元素的列表。 xrange是一个生成器,所以它懒惰地评估。
这为您带来两个好处:
MemoryError