Answers:
在Python 2.x中:
range
创建一个列表,所以如果您这样做range(1, 10000000)
,则会在内存中创建一个包含9999999
元素的列表。
xrange
是一个延迟计算的序列对象。
在Python 3中,range
它等效于python xrange
,并且必须使用来获取列表list(range(...))
。
xrange(x).__iter__()
是一个发电机。
i
都按需评估,而不是初始化。
range会创建一个列表,因此,如果执行
range(1, 10000000)
此操作,则会在内存中创建一个包含9999999
元素的列表。
xrange
是一个生成器,所以它是一个序列对象,是一个懒惰求值的对象。
的确如此,但是在Python 3中,.range()
将由Python 2实现.xrange()
。如果需要实际生成列表,则需要执行以下操作:
list(range(1,100))
记住,使用该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()
无论如何都会为您提供良好的迭代器行为。
python -m timeit "for i in xrange(1000000):" " pass"
the extra overhead is only 0.04 seconds
查看它的正确方法不是正确的,(90.5-51.1)/51.1 = 1.771 times slower
因为它表明,如果这是程序的核心循环,则可能会造成瓶颈。但是,如果这只是一小部分,那么1.77倍并不是很多。
xrange返回一个迭代器,一次只在内存中保留一个数字。range将整个数字列表保留在内存中。
xrange
并没有返回一个迭代。
and only keeps one number in memory at a time
并在其余的都放在请指导我..
一定要花一些时间在图书馆参考上。您越熟悉它,就可以更快地找到此类问题的答案。关于内置对象和类型的前几章特别重要。
xrange类型的优点在于,无论xrange对象代表的范围大小如何,它始终将占用相同的内存量。没有一致的性能优势。
查找有关Python构造的快速信息的另一种方法是docstring和help-function:
print xrange.__doc__ # def doc(x): print x.__doc__ is super useful
help(xrange)
我很震惊,没有人读doc:
此函数非常类似于
range()
,但是返回一个xrange
对象而不是一个列表。这是一种不透明的序列类型,其产生的值与对应的列表相同,而实际上并没有同时存储它们。xrange()
over 的优点range()
是最小的(因为xrange()
在要求输入值时仍必须创建值),除非在内存不足的计算机上使用了非常大的范围或从未使用过范围的所有元素时(例如当循环被使用时)。通常以break
)终止。
range创建一个列表,因此如果执行range(1,10000000),它将在内存中创建一个包含10000000个元素的列表。xrange是一个生成器,因此它懒惰地求值。
这为您带来两个优点:
MemoryError
。在这个简单的示例中,您将发现xrange
over 的优点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
。
现在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
使用range
,它已经创建了一个从0到100000000(耗时)的列表,但是它xrange
是一个生成器,并且仅根据需要(即,如果继续迭代)生成数字。
在Python-3中,该range
功能的实现与xrange
Python-2中的相同,而xrange
在Python-3中已取消了该功能。
快乐编码!
range(x,y)
如果使用for
循环,则返回x和y之间的每个数字的列表,这样range
比较慢。实际上,range
具有较大的Index范围。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
尽管使用循环时并没有什么不同,但仅打印循环时也有差异!
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
其他一些答案提到Python 3淘汰了2.x range
,并将2.x重命名xrange
为range
。但是,除非您使用3.0或3.1(应该没有人使用),否则它实际上是一种不同的类型。
正如3.1文档所说:
范围对象几乎没有行为:它们仅支持索引,迭代和
len
功能。
但是,在3.2+版本中,它range
是一个完整序列,它支持扩展的slice,以及所有collections.abc.Sequence
与语义相同的方法list
。*
并且,至少在CPython和PyPy(当前仅有的两个3.2+实现)中,它还具有index
and 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,而不是向后移植。
在python 2.x中
range(x)返回一个列表,该列表在内存中创建有x个元素。
>>> a = range(5)
>>> a
[0, 1, 2, 3, 4]
xrange(x)返回一个xrange对象,该对象是生成器obj,可按需生成数字。它们是在for循环(惰性评估)期间计算的。
对于循环,这比range()快一点,并且内存效率更高。
>>> b = xrange(5)
>>> b
xrange(5)
xrange()
不是发电机。xrange(n)
.__ iter __()`是。
在循环中针对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实例有何评论?或更好的例子:-)
xrange
看起来稍快一些,尽管使用Python 3进行比较现在是多余的。
timeit
是为了什么。它需要运行很多次,禁用GC,使用最好的时钟代替time
等等,等等
python中的xrange()和range()与用户的工作原理相似,但是区别在于,当我们讨论使用这两个函数分配内存的方式时。
当我们使用range()时,我们为它生成的所有变量分配内存,因此不建议使用更大的no。生成的变量。
另一方面,xrange()一次仅生成一个特定值,并且只能与for循环一起使用以打印所需的所有值。
什么?
range
在运行时返回静态列表。
xrange
返回一个object
(在某种情况下,它的作用类似于生成器,尽管肯定不是一个),并在需要时从中生成值。
什么时候使用?
xrange
如果要生成一个巨大范围(例如10亿)的列表,则可以使用该选项,尤其是当您拥有像手机这样的“内存敏感系统”时。range
,如果你想在列表几次迭代。PS:Python 3.x的range
功能== Python 2.x的xrange
功能。
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()”。
从帮助文档。
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
成为xrange
Python 2.x并被xrange
删除。
根据扫描/打印0-N个项目的要求,range和xrange的工作方式如下。
range()-在内存中创建一个新列表,并将整个0到N个项目(总共N + 1个)打印出来。xrange()-创建一个迭代器实例,该实例扫描项目并仅将当前遇到的项目保留在内存中,因此始终使用相同数量的内存。
如果所需元素只是在列表的开头,那么它可以节省大量时间和内存。
xrange
不创建迭代器实例。它创建一个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%。
range()
在Python中 2.x
此函数本质range()
上是Python中可用的旧函数,它2.x
返回list
包含指定范围内的元素的对象的实例。
但是,这种实现在初始化带有一系列数字的列表时效率太低。例如,for i in range(1000000)
就内存和时间使用而言,要执行的命令非常昂贵,因为它需要将此列表存储到内存中。
range()
在Python 3.x
和xrange()
Python中2.x
Python 3.x
引入了更新的实现range()
(而更新的实现已经可以2.x
通过Python 通过xrange()
功能)。
该range()
漏洞利用一种称为惰性评估的策略。较新的实现未在范围内创建大量元素,而是引入了class range
,这是一个轻量级的对象,代表给定范围内的所需元素,而无需将其显式存储在内存中(这听起来像是生成器,但是惰性求值的概念是不同)。
例如,请考虑以下内容:
# Python 2.x
>>> a = range(10)
>>> type(a)
<type 'list'>
>>> b = xrange(10)
>>> type(b)
<type 'xrange'>
和
# Python 3.x
>>> a = range(10)
>>> type(a)
<class 'range'>
看到这个帖子以查找range和xrange之间的区别:
报价:
range
返回确切的结果:一系列连续的整数,定义的长度以0开头xrange
。但是,将返回“ xrange object”,其作用类似于迭代器
xrange
不是迭代器。返回的列表range
确实支持迭代(列表几乎是可迭代的典型示例)。的整体利益xrange
不是“最小的”。等等。