我们是否应该始终偏爱xrange()而不是range()?
为什么或者为什么不?
解决方案
xrange()效率更高,因为它不是一次生成一个对象列表,而是一次只生成一个对象。一次只能有一个整数,而不是100个整数及其所有开销和放入它们的列表。更快的生成,更好的内存使用,更高效的代码。
除非我特别需要某件事的清单,否则我总是喜欢xrange()
。
仅在需要实际列表时,才应该使用range()而不是xrange()。例如,当我们想修改range()
返回的列表时,或者希望对其进行切片时。对于迭代甚至只是普通索引,xrange()
都可以正常工作(并且通常效率更高)。对于很小的列表,有一点" range()"比" xrange()"要快一点,但是取决于硬件和其他各种细节,收支平衡的长度可能是1或者2;不用担心。更喜欢xrange()
。
出于以下原因选择范围:
1)xrange将在较新的Python版本中消失。这样可以轻松实现将来的兼容性。
2)range将承担与xrange相关的效率。
为了提高性能,尤其是在较大范围内进行迭代时,通常使用xrange()
是更好的选择。然而,在某些情况下,我们可能更喜欢range()
:
- 在python 3中,range()和xrange()一样,而xrange()不存在。如果要编写可在Python 2和Python 3上运行的代码,则不能使用
xrange()
。 - 实际上,在某些情况下,
range()
可能会更快-例如。如果多次重复相同的序列。 " xrange()"每次都必须重建整数对象,但是" range()"将具有真实的整数对象。 (但是,在内存方面,它总是会表现得更差) - xrange()并非在需要真实列表的所有情况下都可用。例如,它不支持切片或者任何列表方法。
[编辑]有几篇文章提到2to3工具将如何升级range()。作为记录,这是在range()和xrange()的一些示例用法上运行该工具的输出。
RefactoringTool: Skipping implicit fixer: buffer RefactoringTool: Skipping implicit fixer: idioms RefactoringTool: Skipping implicit fixer: ws_comma --- range_test.py (original) +++ range_test.py (refactored) @@ -1,7 +1,7 @@ for x in range(20): - a=range(20) + a=list(range(20)) b=list(range(20)) c=[x for x in range(20)] d=(x for x in range(20)) - e=xrange(20) + e=range(20)
如我们所见,当在for循环或者理解中使用时,或者在已经用list()包装的地方,范围保持不变。
range()返回一个列表,xrange()返回一个xrange对象。
xrange()更快,内存使用效率更高。但是收益不是很大。
列表使用的额外内存当然不只是浪费,列表还具有更多功能(切片,重复,插入等)。可以在文档中找到确切的差异。没有硬性规定,请使用所需的。
Python 3.0仍在开发中,但是IIRC range()与2.X的xrange()非常相似,并且list(range())可用于生成列表。
好的,对于xrange与range的权衡和优势,这里的每个人都有不同的看法。它们大体上是正确的,xrange是一个迭代器,range充实并创建了一个实际列表。在大多数情况下,我们不会真正注意到两者之间的差异。 (我们可以将map与range一起使用,但不能与xrange一起使用,但是会占用更多的内存。)
但是,我认为我们希望聚会中听到的是,首选是xrange。由于Python 3中的range是一个迭代器,因此代码转换工具2to3可以将xrange的所有使用正确转换为range,并会针对range的使用抛出错误或者警告。如果要确保将来轻松转换代码,则仅使用xrange,并在确定需要列表时使用list(xrange)。我是在今年(2008年)在芝加哥PyCon上进行的CPython冲刺中学到的。
不,它们都有各自的用途:
迭代时使用xrange()
,因为它节省了内存。说:
for x in xrange(1, one_zillion):
而不是:
for x in range(1, one_zillion):
另一方面,如果我们实际上想要一个数字列表,请使用range()
。
multiples_of_seven = range(7,100,7) print "Multiples of seven < 100: ", multiples_of_seven