一、迭代器
了解迭代器之前要先了解一个概念:
什么是可迭代对象?
在python中但凡有__iter__方法的对象都是可迭代对象
在我们之前学习的数据类型中除了int类型其余的都是可迭代对象!
可迭代的对象包括:str,list,tuple,dict,set,file
1、获取可迭代对象的方式:无须获取,python内置str,list,tuple,dict,set,file都是可迭代对象
2、特点:
内置有__iter__方法的都叫可迭代的对象,执行该方法会拿到一个迭代器对象
其中文件数据类型即是可迭代对象也是迭代器对象。
1、获取迭代器对象的方式:
执行可迭代对象的__iter__方法,拿到的返回值就是迭代器对象
2、特点:
内置有__next__方法,执行该方法会拿到迭代器对象中的一个值
内置有__iter__方法,执行该方法会拿到迭代器本身
# dic={'x':1,'y':2,'z':3}
# iter_dic=dic.__iter__()
# print(iter_dic.__next__())
# print(iter_dic.__next__())
# print(iter_dic.__next__())
# print(iter_dic.__next__())#抛出异常,无值可取。
# s1={'a','b','c'}
# iter_s1=s1.__iter__()
# print(iter_s1.__next__())
# print(iter_s1.__next__())
# print(iter_s1.__next__())
# print(iter_s1.__next__())#抛出异常,无值可取。
# list1=[1,2,3]
# iter_list1=list1.__iter__()
# print(iter_list1.__next__())
# print(iter_list1.__next__())
# print(iter_list1.__next__())
迭代器的优缺点分析
迭代器的优点:
1、提供了一种可不依赖于索引的取值方式
2 、迭代器更加节省内存
迭代器的缺点:
1、取值麻烦,只能一个一个取,只能往后取,
2、并且是一次性的,无法用len获取长度,只有在执行完毕后才知道一共有多少个值。
for循环原理分析:
1、for 循环称之为迭代器循环,in后跟的必须是可迭代的对象
2、for循环会执行in后对象的__iter__方法,拿到迭代器对象
3、然后调用迭代器对象的__next__方法,拿到一个返回值赋值给line,执行一次循环体
4、周而复始,直到取值完毕,for循环会检测到异常自动结束循环
二、生成器
函数内包含有yield关键字,
再调用函数,就不会执行函数体代码,拿到的返回值就是一个生成器对象
def chicken():
print('=====>first')
yield 1
print('=====>sencond')
yield 2
print('=====>third')
yield 3
obj=chicken()
print(obj)
生成器本质就是迭代器,也就是说生成器的玩法其实就是迭代器的玩法
print(obj.__iter__() is obj)
res=obj.__next__()
print(res)
res1=obj.__next__()
print(res1)
res2=obj.__next__()
print(res2)
obj.__next__()
1、iter_obj=obj.__iter__(),拿到迭代器
2、出发iter_obj.__next__(),拿到该方法的返回值,赋值给item
3、周而复始,直到函数内不在有yield,即取值完毕
4、for会检测到StopIteration异常,结束循环
for item in obj:
print(item)
总结yield:
1、为我们提供了一种自定义迭代器的方式,
可以在函数内用yield关键字,调用函数拿到的结果就是一个生成器,生成器就是迭代器
2、yield可以像return一样用于返回值,区别是return只能返回一次值,而yield可返回多次
因为yield可以保存函数执行的状态
def my_range():
print('start........')
n=0
while True:
yield n
n+=1
obj=my_range()
print(obj)
三、面向过程的编程思想
核心是'过程'二字,过程即解决问题的步骤,即先干什么,再干什么。。。。
基于面向过程编写程序就好比在设计一条流水线,是一种机械式的思维方式。
总结优缺点:
优点:复杂的问题流程化,进而简单化
缺点:修改一个阶段,其他阶段都有可能需要做出修改,牵一发而动全身,即扩展性极差
应用:用于扩展性要求低的场景
四、生成器yield的表达式形式:
通过下面一个例子了解yield的表达式形式:
def eat(name):
print('%s ready to eat' %name)
food_list=[]
while True:
food=yield food_list # food='骨头'
food_list.append(food) #food_list=['泔水','骨头']
print('%s start to eat %s' %(name,food))
dog1=eat('alex')
1、必须初始化一次,让函数停在yield的位置
res0=dog1.__next__()
print(res0)
2、接下来的事,就是给用send功能。
send有两方面的功能
1、给yield传值
2、同__next__的功能
res1=dog1.send('泔水')
print(res1)
res2=dog1.send('骨头')
print(res2)
res3=dog1.send('shit')
print(res3)