python生成器推导式_Python生成器/推导式/生成器表达式

一   生成器

生成器的本质就是迭代器

生成器的特点和迭代器一样,取值方式和迭代器一样(__next__(),  send():  给上一个yield传值)

生成器一般由生成器函数或者生成器表达式来创建

其实就是手写的迭代器

1 def func():2 print("111")3 yield 123

4

5 ret =func()6 print(ret)

由于函数中含有yelid,那么这个函数就是生成器函数,  且执行这个函数的时候就不再试函数的执行了,而是获取这个生成器.

如何使用:

deffunc():print("111")yield 123ret=func() #这个时候函数不会被执行而是获取生成器print(ret) #按以前函数的方法执行会打印出地址

s = ret.__next__()print(s)

结果

111

123

yield 是分段执行这个函数, return 是直接停止执行这个函数

1 deffunc():2 print(123)3 yield 456

4 print(789)5 yield 147

6 print(258)7 yield 369

8

9 ret =func()10 print(ret.__next__())11 print(ret.__next__())12 print(ret.__next__())13 print(ret.__next__()) #最后一个yield 执行完毕,再次 __next__()程序会报错, 与return无关

14

15

16 #结果

17 123

18 456

19 789

20 147

21 258

22 369

23 Traceback (most recent call last):24 File "E:/Python/day13/练习.py", line 48, in

25 print(ret.__next__())26 StopIteration # 报错

生成器函数:

1  和普通函数没有区别,里面有   yield   的函数就是生成器函数

2  生成器函数在执行的时候,  默认不会执行函数体,  返回生成器

3 通过生成器的__next__()  分段执行这个函数

4 send()   给上一个  yield   传值,  不能再开头(没有上一个yield)    最后一个yield  也不能用send()

生成器作用:

举一个例子---

比如   你比较喜欢吃鸡蛋,一次性给你买几千个鸡蛋 , 够你吃几年了,  那么这些鸡蛋你怎么存放, 需要很多地方存放,

所以这样你想吃鸡蛋了就去买一个,想吃了就买一个,是不是也能一直吃鸡蛋

ef func():for i in range(1,5000):yield "鸡蛋"+str(i)

ret=func()print(ret.__next__())print(ret.__next__())print(ret.__next__())print(ret.__next__())print(ret.__next__())#结果

鸡蛋1

鸡蛋2

鸡蛋3

鸡蛋4

鸡蛋5

区别 : 如果直接买几千个给你吃 ,  会很占地方, 在程序中就是很占内存,   然而上面的方法是  你想吃就买一个, 不会占地方

所以   生成器非常省内存

send()

方法:   send()方法和__next__方法一样都可以让生成器执行到下一个yield

deffunc():print(1)

a= yield 2

print(a)

b= yield 4

print(b)

c= yield 6

print(c)

d= yield 8gen=func()

ret= gen.__next__()print(ret)

ret1= gen.send("金")print(ret1)

ret2= gen.send("天")print(ret2)

ret3= gen.send("下")print(ret3)#结果

1

2金4天6下8

send() 和  __next__的区别:

1 send  和next()  都是让生成器向下走一次

2 send 可以个上一个yield的位置传递值,不能给最后一个  yield   发送值,在第一次执行生成器代码的时候不能使用  send()

推导式:

列表推导式: 就是用一句话来生成一个列表

语法:   [结果   for循环   判断]

lis = [i for i in range(50) if i%2==1]print(lis)

结果

[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49]

字典推导式

语法:{k:v   for循环    条件判断}

lis = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49]

dic= {i:lis[i] for i in range(len(lis)) if i%3!=0}print(dic)#结果

{1: 3, 2: 5, 4: 9, 5: 11, 7: 15, 8: 17, 10: 21, 11: 23, 13: 27, 14: 29, 16: 33, 17: 35, 19: 39, 20: 41, 22: 45, 23: 47}

集合推导式

语法: {k  for循环    条件判断}

lis = [1,2,3,4,5,6,7,8,12,1,2,3,4,3,3,33,44,55,11,22,33,44,55,333,442,223,3,21]

set= {i for i inlis}print(set)#结果

{1, 2, 3, 4, 5, 6, 7, 8, 33, 11, 12, 44, 333, 21, 22, 55, 442, 223}

生成器表达式:

格式: (结果  for循环  条件判断)

特点:

1  惰性机制

2 只能向前

3 节省内存

重点:      面试题

defadd(a,b):return a +bdeftest():for te in range(4):yieldte

g=test()for i in [2,10]:

g= (add(i,n) for n ing )print(list(g))

上面的程序详解步骤:for i in [2,10]:

g= (add(i,n) for n ing )

由于for循环 i=2的时候没有取值

所以当i= 10的时候才取值

i=2时

g= (add(i,n) for n ing ) 但是没有取值

i=10时

g= (add(i,n) for n in (add(i,n) for n ing ) )

把i 换成10

g= (add(10,n) for n in (add(10,n) for n ing ) )

因为g 是0,1 , 2 , 3所以10 11 12 13g= (add(10,n) for n in (add(10,n) for n ing ) )

g= (add(10,n) for n in (10,11,12,13) )

g= [20,21,22,23]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值