目录
一、生成器
⼀.⽣成器什么是⽣成器.⽣成器实质就是迭代器.
def fun():
print('111')
return '222'
g = fun()
print(g)
将函数中的return换成yield就是⽣成器
def fun():
print('111')
yield '222'
g = fun()
print(g) # <generator object fun at 0x014BB990>
def func():
print("111")
yield 222
gener = func() # 这个时候函数不会执⾏.⽽是获取到⽣成器
ret = gener.__next__() # 这个时候函数才会执⾏,yield的作⽤和return⼀样.也是返回数据
print(ret)
那么我们可以看到,yield和return的效果是⼀样的.有什么区别呢? yield是分段来执⾏⼀个函数.return呢?直接停⽌执⾏函数
def fun1():
print('111')
yield '222'
print('333')
yield '444'
g = fun1()
print(g.__next__())
print(g.__next__()) # 最后一个
print(g.__next__()) # 执行报错了
当程序运⾏完最后⼀个yield.那么后⾯继续进⾏__next__()程序会报错
生成器的好处就是,我要一个拿一个,不用一次性全部拿来,一次性的很占内存;⽣成器是⼀个⼀个的指向下⼀个.不会回去,__next__()到哪,指针就指到哪⼉.下⼀次继续获取指针指向的值.
下面看一下send方法,send和__next__()⼀样都可以让⽣成器执⾏到下⼀个yield
def eat():
print("我吃什么啊")
a = yield "馒头"
print("a=", a)
b = yield "⼤饼"
print("b=", b)
c = yield "⾲菜盒⼦"
print("c=", c)
yield "GAME OVER"
gen = eat() # 获取⽣成器
ret1 = gen.__next__()
print(ret1)
ret2 = gen.send("胡辣汤")
print(ret2)
ret3 = gen.send("狗粮")
print(ret3)
ret4 = gen.send("猫粮")
print(ret4)
send和__next__()区别:1.send和next()都是让⽣成器向下走⼀次2.send可以给上⼀个yield的位置传递值,不能给最后⼀个yield发送值.在第⼀次执⾏⽣成器的时候不能用send,因为上面没有yield
⽣成器可以使⽤for循环来循环获取内部的元素:
def func():
print(111)
yield 222
print(333)
yield 444
print(555)
yield 666
gen = func()
for i in gen:
print(i)
⼆、列表推导式,⽣成器表达式以及其他推导式
1、列表推导式
语法
[想要的结果(变量) for 变量 in 可迭代对象]
a = ['No.%s'%i for i in range(1,10)]
print(a)
列表推导式是通过⼀⾏来构建你要的列表,列表推导式看起来代码简单.但是出现错误之后很难排查.
我们还可以对列表中的数据进⾏筛选
筛选模式:[结果for变量in可迭代对象if条件]
# 获取1-100内所有能被3整除的数
s = [i for i in range(1,101) if i % 3 == 0]
print(s)
2、生成器表达式
生成器表达式与列表推导式基本一样,把[]换成()
gen = (i for i in range(10))
print(gen) # 打印的结果就是⼀个⽣成器.
# 结果:<generator object <genexpr> at 0x106768f10>
# 我们可以使⽤for循环来循环这个⽣成器:
gen = ("麻花藤我第%s次爱你" % i for i in range(10))
for i in gen:
print(i)
# ⽣成器表达式也可以进⾏筛选:
# 获取1-100内能被3整除的数
gen = (i for i in range(1,100) if i % 3 == 0)
for num in gen:
print(num)
生成器表达式和列表推导式的区别
1.列表推导式比较耗内存.⼀次性加载.⽣成器表达式⼏乎不占⽤内存.使⽤的时候才分配和使⽤内存
2.得到的值不⼀样.列表推导式得到的是⼀个列表.⽣成器表达式获取的是⼀个⽣成器.
⽣成器的惰性机制:
⽣成器只有在访问的时候才取值.说⽩了.你找他要他才给你值.不找他要.他是不会执⾏的.
def func():
print(111)
yield 222
g = func() # ⽣成器g
g1 = (i for i in g) # ⽣成器g1.但是g1的数据来源于g
g2 = (i for i in g1) # ⽣成器g2.来源g1
print(list(g)) # 获取g中的数据.这时func()才会被执⾏打印111.获取到222.g完毕.
print(list(g1)) # 获取g1中的数据.g1的数据来源是g.但是g已经取完了.g1也就没有数据了
print(list(g2)) # 和g1同理
三、字典推导式
# 把字典中的key和value互换
dic = {'a': 1, 'b': '2'}
new_dic = {dic[key]: key for key in dic}
print(new_dic)
# 在以下list中.从lst1中获取的数据和lst2中相对应的位置的数据组成⼀个新字典
lst1 = ['jay', 'jj', 'sylar']
lst2 = ['周杰伦', '林俊杰', '邱彦涛']
dic = {lst1[i]: lst2[i] for i in range(len(lst1))}
print(dic)
四、集合推导式
集合推导式可以帮我们直接⽣成⼀个集合.集合的特点:⽆序,不重复.所以集合推导式⾃带去重功能
lst = [1, -1, 8, -8, 12]
# 绝对值去重
s = {abs(i) for i in lst}
print(s)
目录
推导式有,列表推导式,字典推导式,集合推导式,没有元组推导式
⽣成器表达式:(结果for变量in可迭代对象if条件筛选)
⽣成器表达式可以直接获取到⽣成器对象.
⽣成器对象可以直接进⾏for循环.
⽣成器具有惰性机制.
⼀个⾯试题.难度系数99999999....颗星:
# 友情提⽰:惰性机制,不到最后不会拿值 def add(a, b): return a + b def test(): for r_i in range(4): yield r_i g = test() for n in [2, 10]: g = (add(n, i) for i in g) print(list(g))