生成器
本质 : 生成器本质就是 迭代器
三种生成方法 : 1. 通过生成器函数
2. 通过生成器表达式创建
3. 通过数据转换
def func():
print("周杰伦")
return " 昆凌 "
func() ===> 调用函数 ===>打印 周杰伦
print( func() ) ====> 打印返回值 ===> 昆凌
return : 直接返回结果, 结束函数调用
yield : 返回结果 , 可以让函数 分段执行
def func():
print("周杰伦")
yield " 昆凌 " # 函数中包含了 yield ,当前这个函数 就不再是 普通函数了 , 是生成器函数
print( "我是王力宏" )
yield " 李云迪 "
print ( " 迪卡 " )
yield " 谁"
print (" 你好 ")
g=func() # 通过函数 func() 来创建一个生成器 , 需要 _ _next_ _()来执行
print( g._ _next_ _() ) # 执行函数第一步 ====> 周杰伦 昆凌
print( g._ _next_ _() ) # 再执行一步 =====> 王力宏 李云迪
print( g._ _next_ _() ) # 再进行一步====> 迪卡 谁
print( g._ _next_ _() ) # =====> 你好, 报错 # 因为后边没有 yield 了
g=func()
print( g._ _next_ _() )==> 周杰伦 昆凌
print( g._ _next_ _() )===>王立功 李云迪
print( func()._ _next_ _() )====> 周杰伦 昆凌 func() 和g 不一样 , 指向的是两个生成器, 只有两个一模一样才会接着执行下去.否则都是两个不同的
def func():
lst=[ ]
for i in range(1,100)
lst.append("衣服%s" % i)
return lst ======> 一下子全部拿出来100件了, 占内存
def gen():
i=1
while i < 100:
yield "衣服%s" % i =====> 用一件拿一件
i=i+1
g=gen()
print( g._ _next_ _() ) ====> 衣服1 # 每次执行到 yield 下次执行再i=i+1 ,执行到yield
print( g._ _next_ _() ) ====> 衣服2
def func():
yield 11
yield 22
yield 23
yield 24
g=func()
lst=list(g)
print(lst)====>[ 11, 22, 23, 24]
g=func() # 拿到生成器 ,本质是迭代器 迭代器可以迭代 ,就可以for 循环
for i in g:
print(i) # 本质上执行的 就是 _ _next_ _() =====> 11 22 23 24
_ _next_ _() 可以让生成器向下执行一次
send() 也可以让生成器向下执行一次 给上一个 yield 传递一个值 因此 第一个和最后一个不用yield 传值
e.g
def func()
print( "大" )
a=yield " 11 "
print (a)
print("狗")
b=yield "22"
print(b)
print("花")
c=yield "33"
g=func()
print( g._ _next_ _() ) # 执行一步 执行到yield " 11 " 但是a=yield 不会被执行 ====> 大 11
print( g.send(1) ) # 同样执行 将send(1) 传递的 1 赋给a , a=1 到第二个 yield "22" ,但是b=yield不会被执行 =====> a=1,狗,22
print( g.send(2) )# 同样执行 将send(2) 传递的 1 赋给b , b=2 到第三个 yield "33" ,但是c=yield不会被执行 =====> b=2,花,33
print( g.send(3) ) 同样 c=3, 报错 , 因为后边没有 yield 会报 StopIteration
推倒式
列表式推倒 ; 最终给的是列表
语法: [ 最终结果形式 for 变量 in 可迭代对象 if 条件 ]
生成列表中装1到14的数字
lst=[ ]
for i in range(1,15):
lst.append(i)
print(lst)=====>[1,2,...13,14]
列表推倒式
lst=[ "python%s" % i for i in range(1,15)]
print(lst) ====> [python1, python2,...python13, python14]
求 1到100之间能被三整除切小于五十的数的平方
lst=[ i*i for i in range(1,101) if i % 3 ==0 and i<50]
print( lst ) ====> [9, 36, 81, 144, 225, 324, 441, 576, 729, 900, 1089, 1296, 1521, 1764, 2025, 2304]
找出其中 e出现两次的名字
names = [['Tom', 'Billy', 'Jefferson' , 'Andrew' , 'Wesley' , 'Steven' ,
'Joe'],['Alice', 'Jill' , 'Ana', 'Wendy', 'Jennifer', 'Sherry' , 'Eva']]
lst1=[name for name1 in names for name in name1 if name.count("e")==2]
print(lst1)====>['Jefferson', 'Wesley', 'Steven', 'Jennifer']
生成器推倒
将列表推倒式 的 [ ] 换成 ( )
语法: ( 结果 for i in 可迭代对象 if 筛选 )
g=( i for i in range (10) )
print(g)====> 得到生成器的内存地址
print( g._ _next_ _() )====>0
print(list(g))====> [ 1, 2, 3, ... 8,9]
字典推倒式 {结果 for i in 可迭代对象 if 筛选 } ====> key:value
# 把字典中的 key 和 value 互换
dic={ "a" : "b " , " c " : 'd' }
new={ dic[key]= key for key in dic }
print( new )=====> {"b" : "a" , "d": "c"}
集合推倒式 { 结果 for i in 可迭代对象 if 筛选 }
自动去重
lst=["麻花藤", "马云", "张杰" "马云" ," 麻花藤"]
set={i for i in lst }
print( set )=====>{"马云", "麻花藤" ,"张杰"}
面试题
def add(a,b):
return a+b
def test ():
for i in range(4):
yield i
g=test()
for n in [2,10]: # n = 2 和 10 若for in in [ 2, 10 ,5] ====>n就取 5 结果就是 5+5+5+0 5+5+5+1 5+5+5+2 5+5+5+3
g=(add(n,i) for i in g)====> g = (add(n, i) for i in ( add( n , i ) for i in g )===> n取最后一个值 10
print(lst)====> 20 21 22 23 10+0 10+1 10+2 10+3
10+10+0 10+10+1 10+10+2 10+10+3