我们是否应该始终偏爱xrange()而不是range()?

时间:2020-03-06 14:44:22  来源:igfitidea点击:

为什么或者为什么不?

解决方案

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