一、迭代器:
*迭代器协议:对象必须提供一个next方法,执行该方法要返回迭代的下一项,否则引起stopIteration
异常以终止异常
*可迭代对象:实现迭代器协议的对象
如何实现迭代器协议呢? 在对象内部定义__iter__()方法,对象调用该方法,即对象就变成了迭代器对象
* for循环的本质:所有循环的对象都是使用迭代器协议的。
*for循环的执行流程:
其实(列表,元组,字符串,字典,集合,文件对象)并不是可迭代对象,是在for循环中,循环对象调用了__iter__()方法,使得其变成可迭代对象,之后调用next方法,依次打印每一项。for循环可以捕获StopIteration的异常自行停止循环。
例子: list=[1,2,3,4]
for item in list:#先执行iter=list.__iter__(),之后执行iter.__next__()迭代每一项
print(item)
注意: 1.for循环与while循环的区别,for循环可以遍历所有可迭代对象,不管其有序还是无序,二wehile只能通过索引遍历有序对象
2.next(iter) 本方法是python的内置方法,等价于iter.__next__().
*迭代器协议:对象必须提供一个next方法,执行该方法要返回迭代的下一项,否则引起stopIteration
异常以终止异常
*可迭代对象:实现迭代器协议的对象
如何实现迭代器协议呢? 在对象内部定义__iter__()方法,对象调用该方法,即对象就变成了迭代器对象
* for循环的本质:所有循环的对象都是使用迭代器协议的。
*for循环的执行流程:
其实(列表,元组,字符串,字典,集合,文件对象)并不是可迭代对象,是在for循环中,循环对象调用了__iter__()方法,使得其变成可迭代对象,之后调用next方法,依次打印每一项。for循环可以捕获StopIteration的异常自行停止循环。
例子: list=[1,2,3,4]
for item in list:#先执行iter=list.__iter__(),之后执行iter.__next__()迭代每一项
print(item)
注意: 1.for循环与while循环的区别,for循环可以遍历所有可迭代对象,不管其有序还是无序,二wehile只能通过索引遍历有序对象
2.next(iter) 本方法是python的内置方法,等价于iter.__next__().
二、生成器(Generator):
1.定义:一种数据类型,自动实现迭代器协议(别的数据类型需要调用内部的__iter__()方法实现协议),即一种可迭代对象
2.分类及在Python中的表现形式:
*生成器函数:
*常规函数定义,但是使用yield语句而不是return语句返回结果,yield语句一次返回
一个结果,可以多次执行yield语句而return就不可以多次执行。
*生成器函数返回值是生成器,通过调用next方法,访问yield的返回值。每次调用next方法,就执行到函数的第一个yield,并且 挂起函数保存状态,当下次再调用next函数时,会从挂起位置继续执行.
*生成器表达式:
(打印内容 for循环 判断条件)与列表解析式基本一致
注意:本表达式返回的是生成器对象,必须通过调用next方法,才能迭代元素,省内存(只有的使用元素的时候才开辟空间)。
*Python中的三元表达式:
object1 if 表达式(True) else object2
if后面的条件返回True时,该表达式返回结果是object1,否则返回else后面的object2
*列表解析式:
[打印内容 for循环 判断条件]
例如:['pzz%s'%i for i in range(10) if i>5]
注意:判断条件只能写if。同时判断条件是可省略的
这种解析式浪费内存,消耗大。不建议使用(一次性要把所有列表的元素拿出来)
3.注意:迭代器(生成器也是一个特殊的迭代器)只能迭代一次(一次是指把元素完整的遍历一次)
例:求文件中字典中的人口之和,本例子重点练习:生成器函数、生成器表达式以及sum函数
a.txt文件中的内容:
{"population":10}
{"population":20}
{"population":30}
{"population":40}
1.定义:一种数据类型,自动实现迭代器协议(别的数据类型需要调用内部的__iter__()方法实现协议),即一种可迭代对象
2.分类及在Python中的表现形式:
*生成器函数:
*常规函数定义,但是使用yield语句而不是return语句返回结果,yield语句一次返回
一个结果,可以多次执行yield语句而return就不可以多次执行。
*生成器函数返回值是生成器,通过调用next方法,访问yield的返回值。每次调用next方法,就执行到函数的第一个yield,并且 挂起函数保存状态,当下次再调用next函数时,会从挂起位置继续执行.
*生成器表达式:
(打印内容 for循环 判断条件)与列表解析式基本一致
注意:本表达式返回的是生成器对象,必须通过调用next方法,才能迭代元素,省内存(只有的使用元素的时候才开辟空间)。
*Python中的三元表达式:
object1 if 表达式(True) else object2
if后面的条件返回True时,该表达式返回结果是object1,否则返回else后面的object2
*列表解析式:
[打印内容 for循环 判断条件]
例如:['pzz%s'%i for i in range(10) if i>5]
注意:判断条件只能写if。同时判断条件是可省略的
这种解析式浪费内存,消耗大。不建议使用(一次性要把所有列表的元素拿出来)
3.注意:迭代器(生成器也是一个特殊的迭代器)只能迭代一次(一次是指把元素完整的遍历一次)
例:求文件中字典中的人口之和,本例子重点练习:生成器函数、生成器表达式以及sum函数
a.txt文件中的内容:
{"population":10}
{"population":20}
{"population":30}
{"population":40}
def sum_population():
with open('a.txt',encoding="utf-8") as f:
for item in f: #按行读取文件内容
yield item
print(sum(eval(i)['population'] for i in sum_population()))
注意:上述sum的参数:生成器表达式可以不加小括号。sum的参数是可迭代对象。
eval(i)['population'] for i in sum_population()
for循环遍历sum_population(),每一次i就是生成器调用一次next方法,该方法返回值是str,
用eval函数提取str中的数据结构(dict),通过key的方式取得value数值,进行求和运算。
4.生成器补充:
我们可以通过以下三种方式出发生成器的一次迭代:
*生成器.__next__()
*next(生成器)
*生成器.send(object)
例子:
def test():
print("begining...")
first=yield 1
print("1 over",first)
yield 2
print("2 over")
g=test()
g.__next__()
g.send("love")#住里面的object是通过yield赋值给了first。三、生产者与消费者模型
1506

被折叠的 条评论
为什么被折叠?



