生成器
Python-15
@(Python)
一、 生成器
- 生成器是一个函数,在这个
函数内
会出现yield
,调用此函数时,函数体内的代码不会执行,这个被调用的函数就是生成器,格式形式:func()
,此时func()
是一个内存地址- 生成器(
func()
)使用func().__next__()
或next(func())
后,可以得到yield
后面的值- 生成器是自定义后的迭代器,本质是迭代器
1. 使用yield
前
- 函数中没使用
yield
前,调用函数时,函数会执行函数体中的代码
2. 使用yield
后
- 函数中使用
yield
后,调用函数时,函数不会执行函数体中的代码,调用函数变为生成器(一个内存地址),generator
表示生成器
3.生成器使用next
得到yield
的值
- 每次
next
找到yield
的后,对暂停在yield
,并获取yield
后面的值,不会再继续执行下面的代码,下一次next
会从暂停的地方继续走- 一次
next
对应一个yield
返回值
4. range在Python2和Python3中的区别
Python2
中,将range
后内容一次性都加载到内存,Python3
在没有执行时,不占用内存,执行也是一次在内存中只有一个值
5. 使用生成器模拟range的功能
def range_func(start,stop,step=1):
while start < stop:
yield start
start+=step
for i in range_func(1,6):
print(i)
6. yield总结
① yield功能总结
- 提供一种自定义迭代器的方式
yield
可以暂停函数,并且返回值
② yield和return的区别
- 相同点:都是在函数内,都可以返回值,返回值没有类型限制,没有个数限制
- 不同点:
return
只能返回一次值,yield
可以返回多次值
7. yield用法形式(了解)
yield 值
x=yield
x=yield 值
生成器.send()的使用
eat.send('xiang')
的执行顺序,先为当前暂停位置的yield
传值,然后在执行next()
操作next
就是找值,自定义迭代器,找的就是yield
的值- 给函数体传值方式:参数,闭包,send方式(传一参就运行一次,只调了一次函数)
二、三元表达式
- 三元表达式:
res=x if x > y else y
,含义是条件成立时的返回值+if条件+else+条件不成立时的返回值
- 表达式,是由数字、算符、数字分组符号(括号)、自由变量和约束变量等以能求得数值的有意义排列方法所得的组合
三、列表生成式
- 列表生成器,是为了更方便的造列表
- 不要写过多条件,最多再加一个if判断,保持简短整洁
1. 没使用列表生成器前
2. 使用列表生成器后
① 没使用列表生成器前
② 使用列表生成器后
- 把要加入列表的值放在左边,for循环继续执行
③ [i for i in name]形式
- 要求将
['a','b','c','d']
每个元素后面加上_name
④ [成立的条件i for i in name if+条件]形式
- 要求将
['a','b','c','d']
的元素除了c
,后面加上_name
- 先执行右边,在执行左边 右边条件必须成立才执行左边
1、将names=['egon','alex_sb','wupeiqi','yuanhao']中的名字全部变大写
names=[i.upper() for i in names]
print(names)
2、将names=['egon','alex_sb','wupeiqi','yuanhao']中以sb结尾的名字过滤掉,然后保存剩下的名字长度
names=[len(i) for i in names if not i.endswith('sb')]
四、字典生成式
1. key:value形式
- 字典生成式,需要左边以
key:value
的形式
2. zip(k,v)拉链函数
- 遵循迭代器协议,放可迭代对象,原理同
list
等
3.
将元组、列表转成字典
方法一:
方法二:
- 取出,还原
六、集合生成式
①
七、生成器表达式
① (i for i in range(10))
max(数字)
比较一堆数的大小,得出最大值
- 求文件
a.txt
中最长的行的长度(长度按字符个数算,需要使用max
函数)
- 变成迭代器,内存只有一个值,这里使用生成器,不是用列表
- 注意:这里的
max()
不要放在外面,因为放在外面文件就关闭了- 如果
nums=(len(i) for i in f)
变为nums=[len(i) for i in f]
那么
八、小结
- 生成器(迭代器,
iter
后)阶段为准备- 造出生成器时,并没有运行生成器,只有
next
才执行- 使用
next,list(),for,max()
为运行代码阶段- 生成器表达式,不占用内存,同一时间只有一个值,而列表需要全部加载到内存
迭代器对象=可迭代对象.__iter__()
迭代器本身=迭代器对象.__iter__()
下一个值=迭代器对象.__next__()
迭代器和迭代器对象有什么区别?
为什么一个变量名,可以叫迭代器?
迭代器对象,是一个准备值的阶段?