python 生成器 send_python(可迭代对象,迭代器,生成器及send方法详解)

一.可迭代对象

对象必须提供一个__iter__()方法,如果有,那么就是可迭代对象,

像列表,元祖,字典等都是可迭代对象

可使用isinstance(obj,Iterable)方法判断

1 from collections import Iterable,Iterator

2 l={'2':2,'fd':5,'f':6}

3 l_i=l.__iter__()

4

5 print(isinstance(l,Iterable))

6 print(isinstance(l_i,Iterator))

结果:

True

True

二.迭代器

迭代器协议:

对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前退)

符合迭代器协议的就是迭代器。

一个对象是迭代器也是可迭代对象。

from collections import Iterable,Iterator

l={'2':2,'fd':5,'f':6}

l_i=l.__iter__()

s=isinstance(l,Iterable)

print(s)

print(isinstance(l_i,Iterator))

打印结果:

True

True

三.生成器

遵循迭代器协议,相当于一种特殊的迭代器对象

1.生成器表达式

(1)三元表达式(必须是三元)

name = '李'

res='儿子' if name == '李' else '爸爸'

print(res)

打印结果:

儿子

(2)列表解析

所谓列表解析就是列表内包含两元或三元表达式(不能是四元)

1 l=['蚂蚁%s' %i for i in range(10)]

2 l1=['蚂蚁%s' %i for i in range(10) if i >5]

3 print(l)

4 print(l1)

打印结果:

['蚂蚁0', '蚂蚁1', '蚂蚁2', '蚂蚁3', '蚂蚁4', '蚂蚁5', '蚂蚁6', '蚂蚁7', '蚂蚁8', '蚂蚁9']

['蚂蚁6', '蚂蚁7', '蚂蚁8', '蚂蚁9']

一行代码写出9*9乘法表:

print('\n'.join([' '.join(["%dX%d=%-2d" %(i,m,m*i) for i in range(1,m+1)]) for m in range(1,10)]))

原理:.join()方法处理的结果是一个整体的字符串

(3)生成器表达式

1 l=['蚂蚁%s' %i for i in range(10)]#列表

2 l=('蚂蚁%s' %i for i in range(10))#生成器表达式

3 和列表相比不占用内存,使用一次生成一次

4 l=('蚂蚁%s' %i for i in range(10))

5 print(l)

6 print(l.__next__())

7 print(l.__next__())

8 print(next(l))

9 print(next(l))

运行结果:

at 0x000002191AFB5BA0>

蚂蚁0

蚂蚁1

蚂蚁2

蚂蚁3

2.生成器函数

优点:

不会立即执行,节省内存。

有需要时用一个现运行出一个,yield会保留当前状态,下次从当前位置继续运行,直到再次碰到yeild。

对比两个过程理解:

过程一(做出一个卖一个,即调用一次现运行出来一个结果)

1 def product_baozi():

2 for i in range(100):

3 print('正在生产包子%s' %i)

4 yield '一屉包子%s' %i #i=1

5 print('开始卖包子')

6 pro_g=product_baozi()

7 baozi1=pro_g.__next__()

运行结果:

正在生产包子0

过程二:(调用第二次,现运行出来第二个结果)

1 def product_baozi():

2 for i in range(100):

3 print('正在生产包子%s' %i)

4 yield '一屉包子%s' %i #i=1

5 print('开始卖包子')

6 pro_g=product_baozi()

7

8 baozi1=pro_g.__next__()

9 baozi1=pro_g.__next__()

打印结果:

正在生产包子0

开始卖包子

正在生产包子1

3.生成器特性

特性一:for循环可以遍历生成器

def eges():

for i in range(5):

yield '鸡蛋%s' %i #i=1

pro_g=eges()

for i in pro_g:

print(i)

特性二:生成器只能迭代一次,用完就没了。

1 with open('人口普查','r',encoding='utf-8') as f:

2 def g_population():

3 for i in f:

4 yield i

5

6

7 print(sum(eval(l)['population'] for l in g_population()))

8 print(g_population().__next__()) #此句会抛出异常

4.利用生成器实现单线程并发

send()方法,

有一个参数,该参数指定的是上一次被挂起的yield语句的返回值,

并且再次遇到yeild会向send传回一个值。

实例:饭店吃饭

1 import time

2 def consetomer():

3 print('服务员点餐')

4 time.sleep(5)

5 for i in range(5):

6 cai=yield i #接受send的传值,并向下执行,直到结束或遇到下一个yield(此时的yield会向send传回一个值)

7 print('顾客开始吃第%s个菜' %cai)

8

9 def canting():

10 g1=consetomer()

11 print(g1.__next__())

12 print('厨师准备做菜')

13 for i in range(1,5):

14 time.sleep(1)

15 print('第%s个菜做好了' %i)

16 print('第%s个好吃' %g1.send(i)) #传送上一次挂起的yield并等待接受下一次yeild返回值

17 canting()

打印结果:

1 服务员点餐

2 0

3 厨师准备做菜

4 第1个菜做好了

5 顾客开始吃第1个菜

6 第1个好吃

7 第2个菜做好了

8 顾客开始吃第2个菜

9 第2个好吃

10 第3个菜做好了

11 顾客开始吃第3个菜

12 第3个好吃

13 第4个菜做好了

14 顾客开始吃第4个菜

15 第4个好吃

b739ec46bb5c46d9c0aa4ce35ba1ea56.png

关于找一找教程网

本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。

本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。

[python(可迭代对象,迭代器,生成器及send方法详解)]http://www.zyiz.net/tech/detail-94644.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值