Python Range类如何自动执行?
我正在用Python学习数据结构和算法。对于我正在使用的教科书,我重新审视了一个我从未理解的问题。对于下面的用户构建的范围类,为什么像[x代表范围(0,5)]中的x这样的东西会起作用?本质上,为什么索引会自动移动?没有对getitem或len的调用 我已经阅读了Python教程和类部分,但还没有弄明白这一点Python Range类如何自动执行?,python,Python,我正在用Python学习数据结构和算法。对于我正在使用的教科书,我重新审视了一个我从未理解的问题。对于下面的用户构建的范围类,为什么像[x代表范围(0,5)]中的x这样的东西会起作用?本质上,为什么索引会自动移动?没有对getitem或len的调用 我已经阅读了Python教程和类部分,但还没有弄明白这一点 class Range: """A class that mimic's the built-in range class.""" def __init__(self, start
class Range:
"""A class that mimic's the built-in range class."""
def __init__(self, start, stop=None, step=1):
"""Initialize a Range instance.
Semantics is similar to built-in range class.
"""
if step == 0:
raise ValueError('step cannot be 0')
if stop is None: # special case of range(n)
start, stop = 0, start # should be treated as if range(0,n)
# calculate the effective length once
self._length = max(0, (stop - start + step - 1) // step)
# need knowledge of start and step (but not stop) to support __getitem__
self._start = start
self._step = step
def __len__(self):
"""Return number of entries in the range."""
return self._length
def __getitem__(self, k):
"""Return entry at index k (using standard interpretation if negative)."""
if k < 0:
k += len(self) # attempt to convert negative index
if not 0 <= k < self._length:
raise IndexError('index out of range')
return self._start + k * self._step
类别范围:
“”“模拟内置范围类的类。”“”
定义初始化(自、启动、停止=无,步骤=1):
“”“初始化范围实例。
语义类似于内置的range类。
"""
如果步骤==0:
raise VALUERROR('步骤不能为0')
如果停止为无:#范围的特殊情况(n)
start,stop=0,start#应视为范围(0,n)
#计算一次有效长度
self._length=max(0,(停止-启动+步骤-1)//步骤)
#需要了解开始和步骤(但不是停止)以支持__
self.\u start=start
自我。_步骤=步骤
定义(自我):
“”“返回范围内的项目数。”“”
返回自我长度
定义获取项目(self,k):
“”“返回索引k处的条目(如果为负数,则使用标准解释)。”
如果k<0:
k+=len(self)#尝试转换负指数
如果不是0,这是因为Range类实现了有效的所有必要的方法,即\uuu len\uuu
和\uu getitem\uuu
方法。这允许它自动用作iterable,如中所述:
Iterables可用于for循环和许多其他需要
需要序列(zip(),map(),…)。当一个iterable对象
作为参数传递给内置函数iter(),它返回
对象的迭代器。此迭代器适用于在
一组值。使用iterables时,通常不需要
调用iter()或自己处理迭代器对象。for声明
这样做会自动为您创建一个临时的未命名变量
在循环期间保持迭代器。另见迭代器,
序列和生成器
这是因为Range类实现了成为一个有效类所必需的所有功能,即\uuuuu len\uuuu
和\uuu getitem\uuuu
方法。这允许它自动用作iterable,如中所述:
Iterables可用于for循环和许多其他需要
需要序列(zip(),map(),…)。当一个iterable对象
作为参数传递给内置函数iter(),它返回
对象的迭代器。此迭代器适用于在
一组值。使用iterables时,通常不需要
调用iter()或自己处理迭代器对象。for声明
这样做会自动为您创建一个临时的未命名变量
在循环期间保持迭代器。另见迭代器,
序列和生成器
实际上,\uuuu getitem\uuuuu
本身就足够了;它将使用0
调用\uuuuuu getitem\uuuuuuuuuuuuuuuuuuuuuuuuuuu
,然后调用1
,然后调用2
,等等,直到\uuuuuu getitem\uuuuuuuuuuuuuuuuuuuu
引发索引器(它会抑制该索引器,悄悄结束迭代;任何其他异常都会正常冒泡)<代码>\uuuu len\uuuu
不是必需的,即使存在也不会使用。正如您自己的链接所指出的,iterables是“使用\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuo()方法或使用\uuuuuuuuuuuuuuuuuuuuuuuuuuu.@shadowranger你在哪个时区?@roganjosh:UTC-5。但是,当我无法专注于真正的工作时,我会在随机的时间发表文章,作为一种净化心灵的方法。:-)实际上,\uuuu getitem\uuuuu
本身就足够了;它将使用0
调用\uuuuuu getitem\uuuuuuuuuuuuuuuuuuuuuuuuuuu
,然后调用1
,然后调用2
,等等,直到\uuuuuu getitem\uuuuuuuuuuuuuuuuuuuu
引发索引器(它会抑制该索引器,悄悄结束迭代;任何其他异常都会正常冒泡)<代码>\uuuu len\uuuu
不是必需的,即使存在也不会使用。正如您自己的链接所指出的,iterables是“使用\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuo()方法或使用\uuuuuuuuuuuuuuuuuuuuuuuuuuu.@shadowranger你在哪个时区?@roganjosh:UTC-5。但是,当我无法专注于真正的工作时,我会在随机的时间发表文章,作为一种净化心灵的方法。:-)注意:虽然\uuuuu getitem\uuuuuuuuu
已经足够了,但为了效率起见,实现\uuuuuuuuu iter\uuuuuuuuuu
作为生成器函数通常是个好主意;\uu getitem\uuuuuu
中涉及的所有边界检查和重复重新计算使得它比任何合理实现的\uuuu iter\uuuu
慢得多。在本地测试中,基于while
循环的生成器\uuuu iter\uuuu
在较大范围内将运行时间缩短约三分之二,即使在较小范围内也将运行时间缩短一半。请注意,实际的范围
所需时间甚至是基于的重新实施所需时间的十分之一,因此,如果不是课堂练习,请使用附带的电池。:-)注意:虽然\uuuuu getitem\uuuuuuuuu
已经足够了,但为了效率起见,实现\uuuuuuuuu iter\uuuuuuuuuu
作为生成器函数通常是个好主意;\uu getitem\uuuuuu
中涉及的所有边界检查和重复重新计算使得它比任何合理实现的\uuuu iter\uuuu
慢得多。在本地测试中,基于while
循环的生成器\uuuu iter\uuuu
在较大范围内将运行时间缩短约三分之二,即使在较小范围内也将运行时间缩短一半