首先咱们来看看什么是个生成器,生成器本质就是迭代器python
在python中有三种方式来获取生成器面试
1.经过生成器函数app
2.经过各类推到式来实现生成器函数
3.经过数据的转换也能够获取生成器spa
首先,咱们先看一个很简单的函数:指针
def func(): print(11) return 22 ret = func() print(ret) # 运行结果: 11 22
将函数中的return换成yield就是生成器code
运行的结果和上面的不同,为何呢?? 因为函数中存在yield,那么这个函数就是一个生成器函数.对象
咱们在执行这个函数的时候.就再也不是函数的执行了.而是获取这个生成器.如何使用???blog
想一想迭代器,生成器的本质就是迭代器.因此咱们能够直接执行__next__()来执行如下生成器内存
那么咱们能够看到,yield和return的效果是同样的,可是仍是有点区别
yield是分段来执行一个函数
return是直接中止这个函数
当程序运行完最后一个yield,那么后面继续运行__next__()程序会报错
好了生成器咱们说完了.生成器有什么做用呢?
咱们来看一下这个需求,老男孩向楼下卖包子的老板订购了10000个包子.包子铺老板实在一下就所有都作出来了
这样作是没有问题可是咱们目前这么点人吃不完这么多,只能先放到一个地方,要是可以我吃一个老板作一个就完美了.
上下的区别: 第一种是直接把包子都拿来,很占内存也就是很占我们的位置,第二种使用生成器,想吃就拿一个.吃多少个包多少个.生成器是一个一个的,一直向下进行,不能向上.__next__()到哪,指针就指到哪儿.下一次继续就获取指针指向的值
接下来咱们再来认识一个新的东西,send方法
send和__next__()同样均可以让生成器执行到下一个yield
send和__next__()区别:
send 和 next()都是让生成器向下走一次
send能够给上一个yield的位置传递值,不能给最后一个yield发送值,在第一次执行生成器的时候不能使用send()
第一次调用的时候使用send()也能够可是send的参数必须是None
生成器能够for循环来循环获取内部元素:
在python3中提供一种能够直接把可迭代对象中的每个数据做为生成器的结果进行返回
有个小坑,yield from 是将列表中的每个元素返回,因此 若是写两个yield from 并不会产生交替的效果
列表推导式
列表推导式生成器表达式以及其余推导式,首先咱们先看一下这样的代码,给出一个列表,经过循环,想列表中添加1~10:
咱们换成列表推导式是什么样的,来看看:
列表推导式的常⽤写法:
[结果 for 变量 in 可迭代对象]
列表推导式是经过⼀行来构建你要的列表, 列表推导式看起来代码简单. 可是出现错误之
后很难排查.
例. 从python1期到python17期写入列表lst:
筛选模式
[结果 for 变量 in 可迭代对象 if 条件]
生成器表达式
这个其实就将列表推导式俩边的中括号换成小括号就能够了,咱们来看一下
print(l)的时候获取到是:
生成器表达式也能够进行筛选
生成器表达式和列表推导式的区别:
1. 列表推导式比较耗内存,一次性加载.生成器表达式几乎不占用内存.使用的时候才分配和使用内存
2. 获得的值不同,列表推导式获得的是一个列表.生成器表达式获取的是一个生成器
举个例子:
李大锤想吃鸡蛋就上街买了一篮子的鸡蛋放家里,吃的时候拿一个吃的时候拿一个,这样就是一个列表推导式,一次性拿够占地方.
王二麻子也想吃鸡蛋,他上街却买了一只母鸡回家.等他想吃的时候就让母鸡给下鸡蛋,这样就是一个生成器.须要就给你下鸡蛋
生成器的惰性机制: 生成器只有在访问的时候才取值,说白了.你找他要才给你值.不找他要.他是不会执行的.
这是坑,必定要注意,生成器是要值的时候才能拿值,否则就没有啦
字典推导式
根据名字应该也能猜到,推到出来的是字典
集合推导式
集合推导式能够帮咱们直接生成一个集合,集合的特色;无序,不重复 因此集合推导式自带去重功能
总结:
推导式有, 列表推导式, 字典推导式, 集合推导式, 没有元组推导式
生成器表达式: (结果 for 变量量 in 可迭代对象 if 条件筛选)
生成器表达式能够直接获取到⽣成器对象. ⽣成器对象能够直接进行for循环. ⽣成器具备惰性机制.
一个面试题,难度系数99999999课星
友情提示: 惰性机制,不到最后不会拿值