Gointerface接口声明实现及作用详解
464
2022-08-31
python基础(part15)--迭代(python 列表迭代)
鄙人学习笔记 开发工具:Spyder
文章目录
迭代
举个例子1举个例子2for循环原理
可迭代对象iterable
举个例子1举个例子2举个例子3
迭代器对象iterator
yield关键字迭代原理举个例子(我们将之前的MyRange类进行改写)
迭代
每一次对过程的重复为一次”迭代”,而每一次迭代得到的结果,会作为下一次迭代的初始值。例如:循环获取容器中的元素。
举个例子1
可以看出,我们得到的结果和for循环遍历这个列表,得到的结果相同。
如果我们多写一个iterator.__next__(),会怎样呢?
会报错 python警告我们,要 Stop Iteration, 停止迭代!
举个例子2
我们再利用以下方法迭代:
我们发现,我们没有用for循环,也拿到了可迭代对象(列表)内元素。以上两个例子演示了for循环原理。
for循环原理
现在,我们对上面例子中的代码进行解释,进而阐述一下for循环原理
①获取迭代器对象
②获取下一个元素(迭代)
最后,我们总结一下for循环原理:
①获取迭代器对象 ②循环迭代(调用迭代器的__next__()方法) ③捕获StopIteration异常
小问题
问:能够被for循环的条件是什么? 答:具有__iter__()方法的对象。
例子1
使用while + 迭代器,获取元祖(“小白”, “小黄”, “大白”)中所有元素。
代码:
t01 = ("小白", "小黄", "大白")iterator = t01.__iter__()while True: try: item = iterator.__next__() print(item) except: break
例子2
不使用for循环,获取字典{“小白”:0, “小黄”:6, “大白”:7}中的key和value.
代码:
d01 = {"小白":0, "小黄":6, "大白":7}iterator = d01.__iter__()while True: try: key = iterator.__next__() print(key, d01[key]) except: break
结果:
备注:使用迭代器迭代字典,拿到的是字典的key
可迭代对象iterable
定义
具有__iter__()函数的对象,可以返回迭代器对象.
语法
创建可迭代对象:
class 可迭代对象名称: def __iter__(self): return 迭代器
使用可迭代对象:
for 变量名 in 可迭代对象: 语句
原理
迭代器 = 可迭代对象.__iter__()while True: try: print(迭代器.__next__()) except StopIteration: break
举个例子1
但是,如果我们只迭代SkillManager对象会怎样呢?我们看看下面这个例子。
举个例子2
接下来,我们就要让SkillManager可迭代!
我们先要在SkillManager类里增加一个__iter__()方法,使他变为可迭代对象。 这个__iter__()被调用后,应该返回一个迭代器类对象SkillIterator。这个迭代器类对象里应该有一个__next__()方法,用于返回下一个元素。在__next__()方法里应该抛出一个索引越界异常,当被迭代对象全部迭代完后,再获取下一个元素,则会抛出异常。具体情况,我们看看下面的代码。
不错!可迭代对象内元素全部拿到了。
备注1:由上面的过程我们也可以看出,可迭代对象不会直接return它的元素,而是由迭代器return了可迭代对象内的元素。
备注2:若我们用for循环,则它也会先获取迭代器对象,获取完迭代器对象后,再用迭代器对象不断的调用__next__()方法,直到迭代器对象抛出异常,for再进行异常处理。
举个例子3
参照下例代码,定义MyRange类,实现相同效果:
class MyRangeIterator: def __init__(self, stop): self.stop = stop self.start = 0 def __next__(self): if self.start + 1 > self.stop: raise StopIteration() temp = self.start self.start += 1 return tempclass MyRange: def __init__(self, stop): self.stop = stop def __iter__(self): # 创建迭代器对象 return MyRangeIterator(self.stop)iterator = MyRange(5)for item in iterator: print(item)
备注:谁要被for,谁要就有__iter__()方法,这个方法可以获取迭代器,迭代器内部具体怎么写?看需求!迭代器中有__next__(),可以返回下一个元素。
迭代器对象iterator
定义
可以调用__next__()函数,并返回下一个值得对象。
语法
class 迭代器类名:: def __init__(self, 聚合对象): self.聚合对象 = 聚合对象 def __next__(self): if 没有元素: raise StopIteration return 聚合对象内元素
说明
聚合对象通常是容器对象。
作用
使用者只通过一种方式(for循环),便可以简洁明了获取聚合对象中的各个元素,而又无需了解可迭代对象的内部存储结构。
==备注!==若我们在__iter__()方法内不返回自己创建的迭代器对象,而用yield关键字自动生成迭代器对象,会怎样呢?
请看以下案例
①客户端调用__iter__()方法,__iter__()方法不执行, 进入while循环. ②客户端调用__next__()方法,__iter__()方法执行,先执行print("准备返回第一个元素"), 执行到yield语句, 将yield后的数据作为__next__()方法的返回值return给item, 并且暂时离开__iter__()方法, 继续执行while循环中的print(item). ③当再次调用__next__()方法时,从上次离开的代码开始执行,再运行到下一个yield语句,return数据之后,并再次暂时离开. ④待执行完__iter__()方法体,若再次调用__next__()方法,会自动抛出StopIteration异常.
yield关键字迭代原理
原理
如果方法体中包含yield关键字,那么会自动生成迭代器对象.
生成迭代器代码的大致规则: ①将yield关键字前的代码,放到__next__()方法中. ②将yield关键字后的数据,作为__next__()方法的返回值.
举个例子(我们将之前的MyRange类进行改写)
代码:
结果:
若我们不定义类,而只定义包含yield的方法,来满足我们迭代的需求,该怎么做呢?
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~