在Python 2.x中,^{}返回一个列表,而在Python 3.x中,^{}返回一个类型为^{}的不可变序列。
Python2.x:>>> type(range(10))
>>> type(xrange(10))
Python3.x:>>> type(range(10))
在Python2.x中,如果您想要获得一个iterable对象,比如在Python3.x中,您可以使用^{}函数,它返回一个类型为^{}的不可变序列。
Python 2.x中xrange比range的优势: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中的range对象是不可变的序列,因此它们也支持索引。引用range函数文档Ranges implement all of the common sequence operations except concatenation and repetition
...
Range objects implement the collections.abc.Sequence 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
所有这些都有可能通过不可变的range序列实现。
最近,我遇到了一个问题,我认为应该把它包括在这里。考虑一下这个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。但是,它将无限地运行。你能解释为什么吗?
解决方案Because the range returns an immutable sequence, not an iterator object. So, whenever islice is done on a range object, it always starts from the beginning. Think of it as a drop-in replacement for an immutable list. Now the question comes, how will you fix it? Its simple, you just have to get an iterator out of it. Simply change
numbers = range(100)
to
numbers = iter(range(100))
Now, numbers is an iterator object and it remembers how long it has been iterated before. So, when the islice iterates it, it just starts from the place where it previously ended.