$ 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
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 的限制 .
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
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 -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
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的 xrange , xrange 被删除 .
28 回答
range:-range将一次填充所有内容 . 这意味着范围的每个数字都将占用内存 .
xrange:-xrange就像生成器一样,当你需要数字范围但是你不希望它们被存储时它会进入图片,就像你想要用于循环 . 内存效率高 .
range创建一个列表,所以如果你这样做
range(1, 10000000)
它会在内存中用9999999
元素创建一个列表 .xrange
是一个懒惰评估的序列对象 .它应该从@Thiago的提示中添加,在python3中,范围相当于python的xrange
这是事实,但在Python 3中,
.range()
将由Python 2.xrange()
实现 . 如果您需要实际生成列表,则需要执行以下操作:请记住,使用
timeit
模块来测试哪些小代码片段更快!就个人而言,我总是使用
.range()
,除非我正在处理真正庞大的列表 - 正如你所看到的那样,时间方面,对于一百万个条目的列表,额外的开销只有0.04秒 . 正如Corey指出的那样,在Python 3.0中,.xrange()
将会消失,.range()
无论如何都会给你很好的迭代器行为 .xrange
仅存储范围参数并按需生成数字 . 但是,Python的C实现目前将其args限制为C long:请注意,在Python 3.0中只有
range
,它的行为类似于2.xxrange
,但没有最小和最大 endpoints 的限制 .xrange返回一个迭代器,一次只在内存中保留一个数字 . range将整个数字列表保存在内存中 .
花一些时间与Library Reference . 你对它越熟悉,你就能越快找到这样的问题的答案 . 关于内置对象和类型的前几章特别重要 .
查找有关Python构造的快速信息的另一种方法是docstring和help-function:
这为您带来两个好处:
您可以在不获取
MemoryError
的情况下迭代更长的列表 .因为它会懒惰地解析每个数字,如果你提前停止迭代,你就不会浪费时间创建整个列表 .
我很震惊没有人读过doc:
这是出于优化原因 .
range()将从头到尾创建一个值列表(在您的示例中为0 .. 20) . 这将在非常大的范围内成为昂贵的操作 .
另一方面,xrange()更加优化 . 它只会在需要时(通过xrange序列对象)计算下一个值,并且不会创建像range()那样的所有值的列表 .
在这个简单的例子中,您将发现
xrange
优于range
的优势:在
xrange
的情况下,上面的例子没有反映出任何明显更好的结果 .现在看一下以下情况,与
xrange
相比,range
确实非常慢 .使用
range
,它已经创建了一个0到100000000(耗时)的列表,但是xrange
是一个生成器,它只根据需要生成数字,也就是说,如果迭代继续 .在Python-3中,
range
功能的实现与Python-2中xrange
的实现相同,而在Python-3中它们已经废弃xrange
快乐编码!!
range(): range(1,10)返回1到10个数字的列表,并将整个列表保存在内存中 .
xrange(): 与范围()相似,但相反返回列表,返回一个生成按需范围内的数字的对象 . 对于循环,这比range()和内存效率更快 . xrange()对象就像一个迭代器,并根据需要生成数字 . (懒惰评估)
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)
,而且还会保留其中的所有数字 .如果您使用
for
循环,那么它将起作用使用循环时没有太大区别,虽然只是打印时有区别!
在python 2.x中
range(x) 返回一个列表,该列表在内存中使用x个元素创建 .
xrange(x) 返回一个xrange对象,它是一个生成器obj,它根据需要生成数字 . 它们是在for-loop期间计算的(延迟评估) .
对于循环,这比range()稍快,内存效率更高 .
当在循环中测试范围对xrange时(我知道我应该使用timeit,但是使用简单的列表推导示例从内存中迅速查出)我发现了以下内容:
这使:
或者,在for循环中使用xrange:
我的代码段测试是否正常?对xrange较慢的实例有何评论?或者更好的例子:-)
其他一些答案提到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所说:
但是,在3.2中,
range
是一个完整的序列 - 它支持扩展切片,collections.abc.Sequence的所有方法都具有与list
相同的语义 . *并且,至少在CPython和PyPy(当前存在的仅有的两个3.2实现)中,它还具有
index
和count
方法的常量时间实现以及in
运算符(只要您只传递整数) . 这意味着写入123456 in r
在3.2中是合理的,而在2.7或3.1中这将是一个可怕的想法 .python中的xrange()和range()与用户的工作方式类似,但是当我们讨论如何在使用该函数时分配内存时,差异就出现了 .
当我们使用range()时,我们为它生成的所有变量分配内存,因此不建议使用较大的no . 要生成的变量 .
另一方面,xrange()一次只生成一个特定的值,并且只能与for循环一起使用以打印所需的所有值 .
range生成整个列表并返回它 . xrange没有 - 它根据需要在列表中生成数字 .
阅读以下文章,了解范围和xrange之间的比较,并进行图形分析 .
Python range Vs xrange
xrange使用迭代器(动态生成值),range返回一个列表 .
什么?
range
在运行时返回静态列表 .xrange
返回object
(其作用类似于生成器,但肯定不是一个),在需要时从中生成值 .什么时候用哪个?
如果你想生成一个巨大范围的列表,比如10亿,请使用
xrange
,特别是当你有像手机这样的_1083546时 .如果要多次遍历列表,请使用
range
.PS:Python 3.x的
range
function == Python 2.x的xrange
函数 .在扫描/打印0-N项目的要求中,range和xrange的工作原理如下 .
range() - 在内存中创建一个新列表,并将整个0到N个项目(完全为N 1)打印出来 . xrange() - 创建一个迭代器实例,它扫描项目并仅将当前遇到的项目保留在内存中,因此始终使用相同数量的内存 .
如果所需元素有点位于列表的开头,那么它就会保存一个商品时间和记忆 .
对于
range(..)
/xrange(..)
的较小参数,差异会减小:在这种情况下,
xrange(100)
的效率仅提高约20% .每个人都对此有很大的解释 . 但我希望它能为自己看到它 . 我用python3 . 所以,我打开资源监视器(在Windows中!),首先执行以下命令:
然后检查“使用中”内存中的更改 . 这是微不足道的 . 然后,我运行了以下代码:
它立即占用了很大一部分内存 . 而且,我确信 . 你可以自己试试 .
如果您使用的是Python 2X,则将'range()'替换为第一个代码中的'xrange()',将'list(range())'替换为'range()' .
Range 返回 list ,而 xrange 返回 xrange 对象,该对象占用相同的内存,与范围大小无关,因为在这种情况下,每次迭代只生成一个元素并且可用,而在使用范围的情况下,所有元素一次生成,在内存中可用 .
来自帮助文档 .
Python 2.7.12
Python 3.5.2
差异很明显 . 在Python 2.x中,
range
返回一个列表,xrange
返回一个可迭代的xrange对象 .在Python 3.x中,
range
变为Python 2.x的xrange
,xrange
被删除 .此外,如果
list(xrange(...))
将等效于range(...)
.所以
list
很慢 .此外
xrange
确实没有完全完成序列所以's why its not a list, it'是一个
xrange
对象看到这个post找到范围和xrange之间的区别:
报价: