函数生成器、生成器表达式,列表推导式

目录

一、生成器

 ⼆、列表推导式,⽣成器表达式以及其他推导式

 三、字典推导式

四、集合推导式


一、生成器

⼀.⽣成器什么是⽣成器.⽣成器实质就是迭代器.

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))

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

py ~ 小久

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值