一.可迭代对象
对象必须提供一个__iter__()方法,如果有,那么就是可迭代对象,
像列表,元祖,字典等都是可迭代对象
可使用isinstance(obj,Iterable)方法判断
 from collections import Iterable,Iterator
l={'':2,'fd':5,'f':6}
l_i=l.__iter__() print(isinstance(l,Iterable))
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)列表解析
所谓列表解析就是列表内包含两元或三元表达式(不能是四元)
 l=['蚂蚁%s' %i for i in range(10)]
l1=['蚂蚁%s' %i for i in range(10) if i >5]
print(l)
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)生成器表达式
  l=['蚂蚁%s' %i for i in range(10)]#列表
l=('蚂蚁%s' %i for i in range(10))#生成器表达式
和列表相比不占用内存,使用一次生成一次
l=('蚂蚁%s' %i for i in range(10))
print(l)
print(l.__next__())
print(l.__next__())
print(next(l))
print(next(l))
运行结果:
<generator object <genexpr> at 0x000002191AFB5BA0>
蚂蚁0
蚂蚁1
蚂蚁2
蚂蚁3 2.生成器函数
优点:
不会立即执行,节省内存。
有需要时用一个现运行出一个,yield会保留当前状态,下次从当前位置继续运行,直到再次碰到yeild。
对比两个过程理解:
过程一(做出一个卖一个,即调用一次现运行出来一个结果)
 def product_baozi():
for i in range(100):
print('正在生产包子%s' %i)
yield '一屉包子%s' %i #i=1
print('开始卖包子')
pro_g=product_baozi()
baozi1=pro_g.__next__()
运行结果:
正在生产包子0
过程二:(调用第二次,现运行出来第二个结果)
 def product_baozi():
for i in range(100):
print('正在生产包子%s' %i)
yield '一屉包子%s' %i #i=1
print('开始卖包子')
pro_g=product_baozi() baozi1=pro_g.__next__()
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)
特性二:生成器只能迭代一次,用完就没了
 with open('人口普查','r',encoding='utf-8') as f:
def g_population():
for i in f:
yield i print(sum(eval(l)['population'] for l in g_population()))
print(g_population().__next__()) #此句会抛出异常
4.利用生成器实现单线程并发
send()方法,
有一个参数,该参数指定的是上一次被挂起的yield语句的返回值,
并且再次遇到yeild会向send传回一个值。
实例:饭店吃饭
 import time
def consetomer():
print('服务员点餐')
time.sleep(5)
for i in range(5):
cai=yield i #接受send的传值,并向下执行,直到结束或遇到下一个yield(此时的yield会向send传回一个值)
print('顾客开始吃第%s个菜' %cai) def canting():
g1=consetomer()
print(g1.__next__())
print('厨师准备做菜')
for i in range(1,5):
time.sleep(1)
print('第%s个菜做好了' %i)
print('第%s个好吃' %g1.send(i)) #传送上一次挂起的yield并等待接受下一次yeild返回值
canting()

 

打印结果:

 服务员点餐
0
厨师准备做菜
第1个菜做好了
顾客开始吃第1个菜
第1个好吃
第2个菜做好了
顾客开始吃第2个菜
第2个好吃
第3个菜做好了
顾客开始吃第3个菜
第3个好吃
第4个菜做好了
顾客开始吃第4个菜
第4个好吃
 

最新文章

  1. salt源码安装软件和yum安装软件
  2. Python调用C++
  3. angularjs的四大特征
  4. java面试每日一题10
  5. Hello,Akka
  6. jQuery中filter(),not(),split()的用法
  7. Yii 通过widget小物件生成添加表单
  8. [转] 关于UIView
  9. NSIS:判断并安装.NET Framework 4 的例子
  10. 链方法[C# 基础知识系列]专题三:如何用委托包装多个方法——委托链
  11. bzoj3713 [PA2014]Iloczyn|暴力(模拟)
  12. Chipmunk僵尸物理对象的出现和解决(一)
  13. 常用sql语句总结(一)(查询)
  14. Confluence 6 升级自定义的站点和空间关闭缓存
  15. maven学习二(dependencies)
  16. dcoker 安装mysql和数据持久化
  17. 1、Docker概述与安装
  18. 小程序 video 组件同层渲染公测
  19. VS2010/MFC编程入门之三十五(菜单:菜单及CMenu类的使用)
  20. C 标准库 - ctype.h之isalpha使用

热门文章

  1. [&#39;1&#39;, &#39;2&#39;, &#39;3&#39;].map(parseInt) what &amp; why ?
  2. Forest plot(森林图) | Cox生存分析可视化
  3. Redis优雅实现分布式锁
  4. MySQL-时区导致的时间前后端不一致
  5. Android的各大框架整理
  6. kubernetes垃圾回收器GarbageCollector Controller源码分析(二)
  7. .NET Core使用gRPC打造服务间通信基础设施
  8. Jenkins构建Jmeter项目
  9. web安全之php中常见的INI文件配置
  10. MYSQL中HEX、UNHEX函数