7月10日安排
完成所有函数作业和思维导图整理
【45.函数-生成器】
如果数据是有规律的,就可以先生成一个数据,等数据执行的时候再执行,也就是在真正调用数据之前,拿到数据的生成规律,而是拿到生成数据的公式,每取一次加一个容器。
这样的好处就是可以不浪费内存空间。
generator
a2 = (i for i in range(1000))
#只是一个算法,还没有创建
next(a2)
#这就是生成了一个元素,可以一直接着生成
生成器只能往后生成,不能往前调用
【46.函数-斐波那契】
a3 = (i for i in range(5))#这样的循环方式不会报错for具有检测报错机制,while 循环会报错
python2里的range是直接生成列表,如果range的数据很大的话,列表生成就会很慢,但是python3的range就是一个公式,还没有创建;python2里的xrange才会和python3里的range相同。
如果推算的公式比较复杂,那么列表生成式是不行的,因为它只支持三元运算
复杂的算法可以使用函数,比如斐波那契数列
斐波那契数列:除了第一个和第二个数外,任意一个数都可以由前两个数相加得到
1,1,2,3,5,8,13,21,34...
def fib(max):
n,a,b = 0,0,1
while n <max:
print(b)
a,b = b,a+b
n = n+1
return 'done'
-----------------------
def fib(max):
n,a,b = 0,0,1
while n <max:
yield b #
a,b = b,a+b
n = n+1
return 'done'
f = fib(18)
for i in f:
print(i)
输出结果
yield 冻结当前的代码,把函数的执行过程冻结在这里,并且把值返回
好处:可以把函数的每一个值都可以返回出来,有了生成器yield以后,就有数据返回给外部了
函数里有yield,函数内部的代码就不再执行,只是生成一个生成器对象
【47.函数-生成器调用】
生成生成器以后一般是不用next的方法的直接用循环取取值比较好
for循环和while循环的区别:
1.for循环不会报错;2.for循环的时候可以不用next语法
正常情况下就会使用for循环
python3里的range底层也是一个生成器,可以节省内存
python2里的xrange==python3里的range是一样的,都是生成器
【48.函数-函数写生成器】
生成器的创建方式
1.列表生成式(只能用三元运算符进行简单的运算)
2.函数
自己实现一个range
def range2(n):
count = 0
while count <n:
print(count)
count += 1
yield count
new = range2(10)
next(new)
next(new)
yield会暂停函数的执行,并返回当前执行的数据
yield会暂停函数的执行,并返回当前执行的数据
yield会暂停函数的执行,并返回当前执行的数据
重要的事情说3遍!!!
next会唤醒冻结的函数的执行过程,直到遇到下一个yield
总结:
1.生成器可以把函数执行的每一个步骤都通过yield返回出去(yield可以理解为暂停)
【49.函数-生成器send方法】
只要函数里有yield,就代表这个函数就转换为生成器了,
如果一个函数里既有yield又有return,是不能执行return的语句的,不能返回return的值,会报错,因为这个函数已经被转换成生成器了,这个生成器一旦执行结束,就不会再执行了,想再执行是不行的
send的作用
1.唤醒并继续执行生成器
2.发送一个信息到生成器内部
def range2(n):
count = 0
while count <n:
print('count',count)
count += 1
sign = yield count
if sign == 'stop':
break
new = range2(10)
n1 = next(new)
new.send('stop')
yield是返回值,等待下一次执行
next其实就是和send原理一样,只不过是默认发送了一个None,但是send就可以发送任何需要的值了
【50.函数-迭代器】
可以直接用于for循环的数据类型有以下几种:
1.集合数据类型,如list、tuple、dict、set、str等
2.generator,包括生成器和带yield的generator function
这些可以作用域for循环的对象统称为可迭代对象:Iterable
一般情况下可以使用isinstance()判断一个对象是否是迭代器对象
而生成器不但可以作用于for循环,还可以被next()不断调用并返回下一个值,直到最后抛出异常,表示无法继续返回下一值
注意:可以被next()函数调用并不断返回下一值的对象称为迭代器
生成器都是迭代器,都是列表、字典、字符串虽然都是迭代对象,但是都不是迭代器,因为不能使用next()方法,但是可以使用iter()函数将它们变成迭代器
迭代器就是一个数据流,生成迭代器的时候不需要规定终止点,没有终止也不需要终止条件,这样的就表示为数据流。
这是因为Python的Iterator对象表示的是一个数据流,iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出错误,可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个序列,所以Iterator的计算是惰性的,只有在需要返回下一个数据时才回去计算。
总结:
凡是可以作用for循环的对象都是Iterator类型;
生成器一定是迭代器,迭代器不一定是生成器(可以自己写对象)