range() 真的会创建列表吗?
range() 真的会创建列表吗?
我的教授和这个人都声称range
会创建一个值列表。
“注意:range函数只是返回一个包含从x到y-1的数字的列表。例如,range(5, 10) 返回列表[5,6,7,8,9]。”
我认为这是不准确的,因为:
type(range(5, 10)) <class 'range'>
此外,唯一显而易见的访问由range
创建的整数的方法是迭代它们,这让我相信将range
标记为列表是不正确的。
在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
优于range
的优点:
xrange()
比range()
更好(因为xrange()
仍然需要在需要它们的时候创建值),除非在内存不足的机器上使用非常大的范围或者所有的范围元素都没有被使用(例如,当循环通常被break
终止时)。
注意:
此外,访问由
range()
创建的整数的唯一明显方法是迭代它们。
不是这样的,在Python 3中range
对象是不可变序列,它们也支持索引。引用自range
函数的文档,
范围实现了所有常见的序列操作,除了连接和重复。
...
范围对象实现了
collections.abc.Sequence
ABC,并提供诸如包含测试、元素索引查找、切片和对负索引的支持等功能。
例如,
>>> 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。但它会无限运行。你可以说明原因吗?
解决方案
因为
range
返回一个不可变序列,而不是一个迭代器对象。所以,无论何时在range
对象上执行islice
,它始终从开头开始。把它想象成一个不可变列表的替代品。现在问题来了,你怎样才能解决它?很简单,你只需要从中获取一个迭代器。只需把
numbers = range(100)
替换为
numbers = iter(range(100))
现在,
numbers
是一个迭代器对象,它记得它已经迭代了多长时间。所以,当islice
对它进行迭代时,它只会从上次结束的地方开始。
请您在下方输入要翻译的内容。