为什么或者为什么不呢?
当前回答
不,它们都有自己的用途:
迭代时使用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
其他回答
对于性能而言,尤其是在大范围内迭代时,xrange()通常更好。然而,仍然有一些情况下你可能更喜欢range():
In python 3, range() does what xrange() used to do and xrange() does not exist. If you want to write code that will run on both Python 2 and Python 3, you can't use xrange(). range() can actually be faster in some cases - eg. if iterating over the same sequence multiple times. xrange() has to reconstruct the integer object every time, but range() will have real integer objects. (It will always perform worse in terms of memory however) xrange() isn't usable in all cases where a real list is needed. For instance, it doesn't support slices, or any list methods.
[编辑]有几篇文章提到了如何通过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和range的利弊都有不同的看法。它们大多是正确的,xrange是一个迭代器,而range充实并创建了一个实际的列表。在大多数情况下,您不会真正注意到两者之间的区别。(你可以在range中使用map,但不能在xrange中使用,但这会占用更多内存。)
但是,我认为您可能希望听到的是首选的选项是xrange。由于Python 3中的range是一个迭代器,代码转换工具2to3将正确地将xrange的所有使用转换为range,并将抛出一个使用range的错误或警告。如果您希望确保将来可以轻松地转换代码,您将只使用xrange,当您确定需要一个列表时使用list(xrange)。我是在今年(2008年)芝加哥PyCon的CPython冲刺中了解到这一点的。
另一个区别是Python 2实现的xrange()不支持大于C int的数字,所以如果你想使用Python内置的大数字支持来获得一个范围,你必须使用range()。
Python 2.7.3 (default, Jul 13 2012, 22:29:01)
[GCC 4.7.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> range(123456787676676767676676,123456787676676767676679)
[123456787676676767676676L, 123456787676676767676677L, 123456787676676767676678L]
>>> xrange(123456787676676767676676,123456787676676767676679)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: Python int too large to convert to C long
Python 3没有这个问题:
Python 3.2.3 (default, Jul 14 2012, 01:01:48)
[GCC 4.7.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> range(123456787676676767676676,123456787676676767676679)
range(123456787676676767676676, 123456787676676767676679)
选择范围有以下几个原因:
1) xrange将在新的Python版本中消失。这为您提供了方便的未来兼容性。
2) range将具有与xrange相关的效率。
书中给出了一个很好的例子:Practical Python By Magnus Lie Hetland
>>> zip(range(5), xrange(100000000))
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
我不建议在前面的例子中使用range而不是xrange——尽管如此 只需要前五个数字,range计算所有数字,这可能需要很多时间 的时间。使用xrange,这不是问题,因为它只计算所需的数字。
是的,我读了@Brian的回答:在python 3中,range()是一个生成器,xrange()不存在。