在Python 2.x中,
range返回一个列表,但在Python 3.x中,
range返回一个不可变序列,类型为
range。
Python 2.x:
>>> type(range(10))
>>> type(xrange(10))
Python 3.x:
>>> type(range(10))
在Python 2.x中,如果你想得到一个可迭代对象,就像在Python 3.x中一样,你可以使用xrange函数,该函数返回一个类型为xrange的不可变序列。
在Python 2.x中超出范围的xrange的优点:
The advantage of xrange() over range() is minimal (since xrange() still has to create the values when asked for them) except when a very large range is used on a memory-starved machine or when all of the range’s elements are never used (such as when the loop is usually terminated with break).
注意:
Furthermore, the only apparent way to access the integers created by range() is to iterate through them,
不。由于Python 3中的范围对象是不可变序列,它们也支持索引。引用范围函数文档,
Ranges implement all of the common sequence operations except concatenation and repetition
…
Range objects implement the 07005 ABC, and provide features such as containment tests, element index lookup, slicing and support for negative indices.
例如,
>>> range(10, 20)[5]
15
>>> range(10, 20)[2:5]
range(12, 15)
>>> list(range(10, 20)[2:5])
[12, 13, 14]
>>> list(range(10, 20, 2))
[10, 12, 14, 16, 18]
>>> 18 in range(10, 20)
True
>>> 100 in range(10, 20)
False
所有这些对于不可变范围序列是可能的。
最近,我面临一个问题,我认为在这里包括是适当的。考虑这个Python 3.x代码
from itertools import islice
numbers = range(100)
items = list(islice(numbers, 10))
while items:
items = list(islice(numbers, 10))
print(items)
人们会期望这个代码打印每十个数字作为列表,直到99。但是,它会无限运行。你能理解为什么吗?
解
因为范围返回不可变序列,而不是迭代器对象。因此,每当对范围对象执行islice时,它始终从头开始。把它想象成一个不可变的列表的替代。现在的问题来了,你将如何解决它?它的简单,你只需要得到一个迭代器。只是改变
number = range(100)
至
numbers = iter(range(100))
现在,数字是一个迭代器对象,它记住了以前迭代了多长时间。所以,当islice迭代它,它只是从它之前结束的地方开始。