g=generator() #调用生成器
list(g)
从生成器中取值的集中方法
- next
- for
- 数据类型的强制装换 全部取完 占内存
回顾:
迭代器和生成器
迭代器:
双下方法 : 很少直接调用的方法。一般情况下,是通过其他语法触发的
可迭代的 —— 可迭代协议 含有__iter__的方法('__iter__' in dir(数据))
可迭代的一定可以被for循环
迭代器协议: 含有__iter__和__next__方法
迭代器一定可迭代,可迭代的通过调用iter()方法就能得到一个迭代器
迭代器的特点:
很方便使用,且只能取所有的数据取一次
节省内存空间
生成器
生成器的本质就是迭代器
生成器的表现形式
生成器函数
生成器表达式
生成器函数:
含有yield关键字的函数就是生成器函数
特点:
调用函数的之后函数不执行,返回一个生成器
每次调用next方法的时候会取到一个值
直到取完最后一个,在执行next会报错
写生成器实现:有一个文件,从文件里分段读取内容
readline
read(10)
在读出来的内容前面加上一个'***',再返回给调用者
def generator():
for i in range(20):
yield '哇哈哈%s'%i
g = generator() 调用生成器函数得到一个生成器
print(list(g))
ret = g.__next__() 每一次执行g.__next__就是从生成器中取值,预示着生成器函数中的代码继续执行
print(ret)
num = 0
for i in g:
num += 1
if num > 50:
break
print(i)
今日 进阶版 优化
def gen():
print(123)
yield 1
print(456)
yield 2
g=gen()
ret=g.__next__()
print("***",ret)
ret=g.__next__()
print("***",ret)
ret=g.__next__()
优化二
def gen():
print(123)
yield 1
print(456)
yield 2
g=gen()
ret=g.__next__()
print("***",ret)
ret=g.send('hello')
print("***",ret)
优化3 的作用
def gen():
print(123)
con=yield 1
print("======",con)
print(456)
yield 2
g=gen()
ret=g.__next__()
print("***",ret)
ret=g.send('hello') #返回 传值
print("***",ret)
send 获取下一个的值的效果和 next 基本一致
只是在获取下一个值的时候 给上一个yield的位置 传递一个数据
!!第一次使用生成器的时候,必须使用next 获取下一个值
!!最后一个yield不能接受 外部的值
解决最后一个yield的方法
def gen():
print(123)
con=yield 1
print("======",con)
print(456)
res= yield 2
yield
g=gen()
ret=g.__next__()
print("***",ret)
ret=g.send('hello') #返回 传值
print("***",ret)
获取移动中平均值
def avg(): ##只能执行一次
sum=0
count=0
avg=0
num=yiel
sum+=num
count+=1
av=sum/c
yield av
av=avg()
av.__next__(
avg1=av.send
print(avg1)
嘿嘿::
更改执行多次
def avg():
sum=0
count=0
avg=0
num=yiel
sum+=num
count+=1
av=sum/c
yield av
av=avg()
av.__next__(
avg1=av.send
print(avg1)
再次优化
def avg():
sum=0
count=0
avg=0
while True:
num=yield
sum+=num
count+=1
avg=sum/c
av=avg()
av.__next__()
avg1=av.send(10)
avg1=av.send(10)
print(avg1)
生成器 yield from 输出每个字符
python 2
def gen():
a='abcdf'
b='123456'
for i in a:
yield i
for i in b:
yield i
b=gen()
for i in b:
print(i)
python 3的新特性
def gen():
a='abcdf'
b='123456'
yield from a ##new
yield from b
b=gen()
for i in b:
print(i)
生成器表达式和 列表表达式
#格式 for 循环 [ i for i range(11)]
print(egg_list)
######x效果一样的
egg_list=[] ###
for i in range(10)
egg_list.append('鸡蛋%s'%i)
print(egg_list)
'______________________________________________________'
egg_list=['鸡蛋%s'%i for i in range(10)] #列表推倒式
生成器表达式
g=(i for i in range(10)) #生成器表达式
print(g)
for i in g:
print(i)
#括号不一样 返回值不一样 ===几乎不占用内存 (生成器表达式的优点)
egg_list=[‘鸡蛋%s’%i for i in range(10)] ##三元运算符 简化版
推倒式: 遍历和筛选
[满足条件的元素相关的操作 for 元素 in 可迭代数据类型 if 元素相关的条件] #筛选器
-
30之内能被三整除的数
res=[for i in range(30) if i%3==0] -
找到嵌套列表中名字含有两个‘e’的所有名字·
names=[[‘tony’,‘sony’],[‘tim’][‘thomas’]] #男女分开
ton=[name for list in names for name in list if name.count(‘e’)==2]
字典推倒式
- 字典颠倒
mc={‘a’:10, ‘b’:34}#want {10:‘a’,34:‘b’}
mc1={ mc[k]:k for k in mc}
print(mc1)
- 合并大小写对应的value值 将k 统一成小写
mc={'A':10,'b':34,'c':54,'a':7} {'a':17}
mcase_frequency = {k.lower(): mcase.get(k.lower(), 0) + mcase.get(k.upper(), 0) for k in mcase}
print(mcase_frequency)
print(d.get(‘g’,0)) # 字典 get 不到的话返回提攻的默认值0
集合推倒式 自带去重复的
squ={x**2 for x in [1,-1,2]}
print(squ)
惰性运算