迭代器iter

1.迭代的含义:

每次生成的结果依赖于上一次。问路,先问第一个人,第
一个人不知道他就说第二个人知道,然后去找第二个人。第二个人不知道
就说第三个人知道,然后去找第三个人

2.递归的含义:

问路,先问第一个人,不知道就第一个人问第二个人,还
不知道就第二个人问第三个,还不知道就第三个人问第四个。如果第四
个知道了就告诉第三个,第三个告诉第二个,一直反复
然后告诉给原来问路的那个人

3.迭代器协议:

对象必须要提供一个next的下一步的方法。就像生孩子传宗接代一样,要按着
一个方法一代接一代下去,也有可能会出现异常,终止迭代。(只能接着往下
走没有后退的路)

4.可迭代对象:实现了迭代器协议的对象。

5.for循环只能遍历可迭代对象。

(字符串,列表,元组,字典,集合,文件对象)这些其实不是可迭代对象,因为
他们没有.next的附加方法,但是在for调用他们的时候,调用了他们内部的__iter__
方法,把他们都变成了可迭代对象。

x='hello'      #变字符串的成可迭代
diedai = x.__iter__()
print(diedai.__next__()) #本句也可以改成print(next(diedai))
print(diedai.__next__())
dic={'a':1,'b':2} #变字典的成可迭代
died=dic.__iter__()
print(died.__next__())
print(died.__next__())
died1=dic.values().__iter__()
print(died1.__next__())
print(died1.__next__())

生成器

1.生成器定义:

生成器是一种数据类型,这种数据类型自动实现了迭代器协议
,不用执行iter方法,它本身就是可迭代对象。它可以直接用.next()。生成器很
节省内存,next()显示下一个之后上一个会被删掉。

2.生成器在python内有两种表达方式

第一种:

生成器函数,在函数内用yield语句而不是return可以将函数变成生成
器函数。

def test():
yield 1
yield 'sb'
yield 'nt'
g=test()
print(g.__next__())
print(g.__next__())

第二种:生成器表达式

首先需要了解三元表达式

#三元表达式,先看中间再看左边最后右边

name='alex'
res='sb' if name == 'alex' else 'shuai' #本句为3元表达式
#如果名字是alex就把sb赋值给res,if的结果写在前面,而else的结果帅写后面
print(res)

还需要了解一下列表解析

#列表解析
egglist=[] #建立一个空的列表
for i in range(10):
egglist.append('鸡蛋%s' %i)
print(egglist)
#接下来用列表解析优化
l=['鸡蛋%s' %i for i in range(10)]
#用列表解析和三元表达式弄出标签大于5的鸡蛋
l1=['鸡蛋%s' %i for i in range(10) if i>5]
print(l)
print(l1)

接下来来说生成器表达式

生成器表达式就是列表解析把[]改成()

laomuji=('鸡蛋%s'  %i for i in range(10))
#此时laomuji就已经是生成器表达式,可迭代对象
print(laomuji.__next__())
print(laomuji.__next__())
print(laomuji.__next__())
print(laomuji.__next__())

实例:现做现卖包子

#使用__next__()是走到yield的位置就跳出,下一次next从当前跳出位置开始
def product_baozi():
for i in range(1,100): #循环做包子
print('正在生产包子')
yield '第 %s 个包子' %i #第一次调用next来到这跳出,下一次next调用从这开始
print('开始卖包子')
pro_g=product_baozi()
print(pro_g.__next__())
print(pro_g.__next__())
print(pro_g.__next__())

实例2:统计出字典中的每个地方的人口占据的人口比例

人口.txt内的内容
{'name':'北京','population':'10'}
{'name':'山东','population':'1000'}
{'name':'山西','population':'30010'}
{'name':'河北','population':'15200'}
{'name':'台湾','population':'750'}

程序:

#采用readline函数进行实现 算出人口比例
f=open('人口','r',encoding='utf8')
ret1=[]
ret=[]
i=0
i1=0
while i<5:
ret=eval(f.readline())
ret1.append(int(ret['population']))
i=i+1
qiuhe=sum(ret1)
print(qiuhe)
while i1<5:
print('%s %%' %(ret1[i1]/qiuhe))
i1=i1+1

#采用生成器来做

def getpopulation():
f=open('人口','r',encoding='utf8')
for i in f:
yield i
g=getpopulation()
qiuhe=0
qiuhe=sum(int(eval(i1)['population']) for i1 in g) #先看右边生成器迭代取每列,然后
print(qiuhe) #看左边把每列转换字符串,取人口,变数字型
g=getpopulation()
for p in g:
pnumber=int(eval(p)['population'])
print(pnumber/qiuhe)

生产消费者模型:

两者是并发运行的,一个生产然后跳到另一个消费,如此循环
采用生成器yield可以达到这个效果

1.首先需要了解启动生成器的第三种方法

之前只学过__next__和next()两种方法,还有一种方法用send

# def test():
# print('开始了')
# yield 1
# print('第一次')
# yield 2
# t=test()
# t.send(None) #用none的话和t.__next__()没区别
#send的优势是可以将一个值赋值给yield的那一行位置的形参
def test1():
print('开始了')
shit=yield 1
print('第一次',shit)
fuck=yield 2
print('第2次')
print(fuck)
yield 3
t=test1()
t.send(None) #光标运行至yield1
res2=t.send('m870') #此时m870将传递给yield1然后传给shit,而且光标将运行到yield2
t.send('m8') #当前光标在yield2,传m8给yeild2给fuck,而且光标运行到yield3
print('\n')
print(res2) #而且可以通过res2来接收yield的ruturn值

2.接下来来看并发的生产消费模型

import time
def consumer(name):
print('我是%s,我准备开始吃包子' %name)
while 1:
time.sleep(1)
print('包子生产好了')
baozi=yield
print('我是%s,我开始吃%s包子' %(name,baozi))
def producer(name,eattime):
c1=consumer(name) #启动生成器
c1.__next__() #光标移动至yield
for i in range(eattime):
time.sleep(1)
c1.send('第%s个屎馅' %i) #将屎馅传给yield传给baozi,因为while一直循环,光标到下一次yeild
producer('沙比',3)

最新文章

  1. LINQ教程
  2. Linux开机后 systemd 自动启动 ceph osd mon进程
  3. 三、jQuery--jQuery基础--jQuery基础课程--第6章 jQuery 事件与应用
  4. gitlab 用户头像不能显示的问题
  5. hdu 4063 福州赛区网络赛 圆 ****
  6. 优化磁盘I/O
  7. js 10秒钟倒计时
  8. 配置apache虚拟主机的实例总结
  9. Mvc学习笔记(2)
  10. GridView合并多行列值
  11. PRINCE2的价值是什么?
  12. ASP实现计算机爱好者网站,可以直接浏览
  13. STL复习之 map &amp; vector --- disney HDU 2142
  14. float样式的使用
  15. 利用 JMetal 实现大规模聚类问题的研究(一)JMetal配置
  16. python 参数传递 传值还是传引用
  17. MySQL误删数据
  18. P1383 高级打字机
  19. Mysql 之权限体系
  20. java爬取网页Unicode转UTF-8中文

热门文章

  1. Sqlmap 学习笔记1:sqlmap参数
  2. 阿里云服务器Centos7上使用Nginx部署https协议的网站
  3. Mysql主从数据库(master/slave),实现读写分离
  4. linux中搭建phpmyadmin详细流程
  5. C# 生成图片验证码 图片缩略图 水印
  6. 如何查看打印机的IP地址和MAC地址
  7. ribbon源码分析
  8. Java学习日报8.5
  9. mysql8.0.x中datasource信息
  10. java线程,进程,多线程