Tei*_*ion 690 python loops range xrange python-2.x
显然xrange更快但我不知道为什么它更快(除了轶事到目前为止没有证据表明它更快)或者除此之外还有什么不同
for i in range(0, 20):
for i in xrange(0, 20):
Run Code Online (Sandbox Code Playgroud)
小智 782
range创建一个列表,所以如果你这样做range
,就会在内存中用range(1, 10000000)
元素创建一个列表.
9999999
是一个懒惰评估的序列对象.
它应该从@Thiago的提示中添加,在python3中,范围相当于python的xrange
Cor*_*rey 220
range创建一个列表,所以如果你这样做
range(1, 10000000)
,就会在内存中用9999999
元素创建一个列表.
xrange
为发电机,所以它是一个序列对象是一个计算结果懒惰地.
这是事实,但在Python 3中,.range()
将由Python 2实现.xrange()
.如果您需要实际生成列表,则需要执行以下操作:
list(range(1,100))
Run Code Online (Sandbox Code Playgroud)
Joh*_*uhy 110
请记住,使用该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
Run Code Online (Sandbox Code Playgroud)
就个人而言,我总是使用.range()
,除非我正在处理真正庞大的列表 - 正如你所看到的,时间方面,对于一百万个条目的列表,额外的开销只有0.04秒.正如Corey指出的那样,Python 3.0 .xrange()
将会消失,.range()
无论如何都会给你很好的迭代器行为.
efo*_*nis 64
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]
Run Code Online (Sandbox Code Playgroud)
请注意,在Python 3.0中只有range
它,它的行为类似于2.x,xrange
但没有最小和最大端点的限制.
Ben*_*ein 38
xrange返回一个迭代器,一次只在内存中保留一个数字.range将整个数字列表保存在内存中.
Ant*_*nen 28
花一些时间阅读图书馆参考资料.你对它越熟悉,你就能越快找到这样的问题的答案.关于内置对象和类型的前几章特别重要.
xrange类型的优点是xrange对象总是占用相同数量的内存,无论它所代表的范围大小.没有一致的性能优势.
查找有关Python构造的快速信息的另一种方法是docstring和help-function:
print xrange.__doc__ # def doc(x): print x.__doc__ is super useful
help(xrange)
Run Code Online (Sandbox Code Playgroud)
Luc*_* S. 13
range创建一个列表,因此如果你执行range(1,10000000),它会在内存中创建一个包含10000000个元素的列表.xrange是一个生成器,所以它懒惰地评估.
这为您带来两个好处:
MemoryError
.QAZ*_*QAZ 11
这是出于优化原因.
range()将从头到尾创建一个值列表(在您的示例中为0 .. 20).这将在非常大的范围内成为昂贵的操作.
另一方面,xrange()更加优化.它只会在需要时(通过xrange序列对象)计算下一个值,并且不会创建像range()那样的所有值的列表.
Use*_*yen 11
你会发现的优势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
Run Code Online (Sandbox Code Playgroud)
上面的例子并没有反映任何实质上更好的情况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
Run Code Online (Sandbox Code Playgroud)
有了range
它,它已经创建了一个从0到100000000(耗时)的列表,但它xrange
是一个生成器,它只根据需要生成数字,也就是说,如果迭代继续.
在Python-3中,range
功能的实现与Python-2中的实现相同xrange
,而它们xrange
在Python-3中已经废弃了
快乐编码!!
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)
Run Code Online (Sandbox Code Playgroud)
如果你使用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
Run Code Online (Sandbox Code Playgroud)
使用循环时没有太大区别,虽然只是打印时有区别!
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
Run Code Online (Sandbox Code Playgroud)
在python 2.x中
range(x)返回一个列表,该列表在内存中使用x元素创建.
>>> a = range(5)
>>> a
[0, 1, 2, 3, 4]
Run Code Online (Sandbox Code Playgroud)
xrange(x)返回一个xrange对象,它是一个生成器obj,它根据需要生成数字.它们是在for-loop期间计算的(延迟评估).
对于循环,这比range()稍快,内存效率更高.
>>> b = xrange(5)
>>> b
xrange(5)
Run Code Online (Sandbox Code Playgroud)
当在循环中测试范围对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)
Run Code Online (Sandbox Code Playgroud)
这使:
$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?
Run Code Online (Sandbox Code Playgroud)
或者,在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
Run Code Online (Sandbox Code Playgroud)
我的代码段测试是否正常?对xrange较慢的实例有何评论?或者更好的例子:-)
一些其他的答案中提到的Python 3淘汰2.X的range
,并更名为2.X的xrange
到range
.但是,除非你使用3.0或3.1(没有人应该),否则它实际上是一种不同的类型.
正如3.1文档所说:
Range对象的行为很少:它们只支持索引,迭代和
len
函数.
但是,在3.2+中,range
是一个完整的序列 - 它支持扩展切片,并且所有方法都collections.abc.Sequence
具有相同的语义list
.*
而且,至少在CPython和PyPy(目前只存在两个3.2+实现)中,它还具有index
和count
方法和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,而不是向后移植.