Python迭代器与生成器用法实例分析


Posted in Python onJuly 09, 2018

本文实例讲述了Python迭代器与生成器用法。分享给大家供大家参考,具体如下:

迭代器,迭代的工具

什么是迭代器?

指的是一个重复的过程,每一次重复称为一次迭代,并且每一次重复的结果是下一次重复的初始值

l=['a','b','c']
count=0
while count <len(l):
  print(l[count])
  count+=1

为什么要有迭代器

1、对于序列类型:str,list,tuple,可以依赖索引来迭代取值
2、对于dict,set,文件,python必须为我们提供一种不依赖于索引的迭代取值的方式—>迭代器

可迭代的对象

对象内置函数带有iter的都称为可迭代的对象

str   name='lqx' name.__iter__
list  l=[1,2,3]  l.__iter__
tuple  t=(1,2,3)  t.__iter__
dict  d={'name':'lqx','age':18,'sex':'male'} d.__iter__
set   s={'a','b','c'} s.__iter__
file  f=open('a.txt','w',encoding='utf-8')  f.__iter__

迭代器对象

文件即是可迭代对象,也是迭代器对象

f.__iter__
f.__next__

迭代器总结

1、可迭代对象不一定是迭代器对象
2、迭代器对象一定是可迭代的对象
3、调用obj.iter()方式,得到的是迭代器对象(对于迭代器对象,执行iter得打的仍然是它本身)

d={'name':'egon','age':18,'sex':'male'}
d_iter=d.__iter__() #使用iter之后,生成的d_iter是迭代器
print(d_iter,type(d_iter))
print(d_iter.__next__()) #next的俩种使用方式
print(next(d_iter))
print(next(d_iter))
print(next(d_iter)) #迭代器d_iter没有值的时候,会抛出异常:StopIteration
print(next(d_iter))

如何去除next取不到中导致StopIteration异常

#下面是如何去除StopIteration异常
while True:
  try:   #使用try:去除异常
    print(next(d_iter))
  except StopIteration: #去除异常StopIteration
    break

for循环详解:

1、调用in后面的obj_iter=obj.iter()
2、k=obj_iter.next()
3、捕捉stopiteration异常,结束迭代

d={'name':'lqx','age':19,'sex':'male'}
for k in d:
  print(k)

迭代器优缺点总结

优点:

1、提供一种统一的、不依赖与索引的取值方式,为for循环提供了依据
2、迭代器同一时间在内存中只有一个值—>更节省内存空间

缺点:

1、只能往后取,并且是一次性的
2、不能统计值的个数,即长度

l=[1,2,3,4,5]
l_iter=l.__iter__()
print(next(l_iter))
print(next(l_iter))
print(next(l_iter))
print(len(l_iter))  #TypeError: object of type 'list_iterator' has no len()

生成器,就是生成迭代器

什么是生成器

只要在函数体内出现yield关键字,那么再执行函数就不会执行函数代码,会得到一个结果,该结果就是生成器

def func():
  print('---->1')
  yield 1
  print('---->2')
  yield 2
  print('---->3')
  yield 3
a=func()
print(next(a)) #next(a),会执行到第一个yield结束,返回结果是yield后面的返回值
next(a)
next(a)

生成器就是迭代器

g=func()
res1=next(g)
print(res1)
res2=next(g)
print(res2)
res3=next(g)
print(res3)
>>>
---->1
1
---->2
2
---->3

yield的功能

yield为我们提供了一种自定义迭代器对象的方法

yield与return的区别:

1、yield可以返回多次值
2、函数暂停与再继续的状态是由yield帮我们保存的
3、yield在函数中也就是暂停的意思,并且返回yield后面的值

obj=range(1,1000000000000,2)
obj_iter=obj.__iter__()
print(next(obj_iter))
print(next(obj_iter))
print(next(obj_iter))
print(next(obj_iter))

制作一个range内置函数:

#制作一个range函数
def range_it(start,stop,step=1):
  while stop > start:
    yield start
    start=start + step
for i in range_it(1,20,2):
  print(i)

制作一个类似于linux中管道的小程序

import time
# 小练习::tail -f access.log | grep '404'
def tail(filepath): #检测是否有新的写入信息,如果有一条就给yield,作为函数的返回结果。
  with open(filepath,'rb') as f:
    f.seek(0,2)
    while True:
      line=f.readline()
      if line:
        yield line
      else:
        time.sleep(0.05)
def grep(lines,pattern): #传入tail检测到新增加的行,然后打印出来这一行并赋值给line,再做判断404,在就使用yield返回这一行
  for line in lines:
    # print(line)
    line=line.decode('utf-8')
    if pattern in line:
      yield line
lines=grep(tail('a.txt'),'404') #grep()函数执行的结果返回的yield的值,给他赋值,
for line in lines:    #使用for去循环取出lines中的值
  print(line)

生成器了解知识点:yield表达式的用法

生成器使用yield表达式,就是给yield初始化下,然后给他传任意值
这里需要先给yield传入一个None的值

e.send:

1、从暂停的位置将值传给yield
2、与next一样

def eater(name):
  print('%s ready to eat' %name)
  food_list=[]
  while True:
    food=yield food_list
    food_list.append(food)
    print('%s start to eat %s' %(name,food))
e=eater('alex')
#首先要做一个初始化的操作:也就是必须要先给yield传入一个None的值。
print(e.send(None)) #next(e)
print(e.send('一桶水')) #给yield赋值一次,然后会执行下面的代码,然后循环到下一个yield停止
print(e.send('一盘骨头'))

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
初步剖析C语言编程中的结构体
Jan 16 Python
Python3连接MySQL(pymysql)模拟转账实现代码
May 24 Python
Python列表切片用法示例
Apr 19 Python
用python 实现在不确定行数情况下多行输入方法
Jan 28 Python
python实现大文本文件分割
Jul 22 Python
Python shutil模块用法实例分析
Oct 02 Python
python 解决cv2绘制中文乱码问题
Dec 23 Python
如何基于Python + requests实现发送HTTP请求
Jan 13 Python
pandas分批读取大数据集教程
Jun 06 Python
python如何对链表操作
Oct 10 Python
python 怎样进行内存管理
Nov 10 Python
Python中tqdm的使用和例子
Sep 23 Python
numpy的文件存储.npy .npz 文件详解
Jul 09 #Python
Python实现聊天机器人的示例代码
Jul 09 #Python
Atom的python插件和常用插件说明
Jul 08 #Python
Python中pip更新和三方插件安装说明
Jul 08 #Python
python中sys.argv函数精简概括
Jul 08 #Python
python输出100以内的质数与合数实例代码
Jul 08 #Python
详解Python中的正则表达式
Jul 08 #Python
You might like
利用discuz自带通行证整合dedecms的方法以及文件下载
2007/03/06 PHP
PHP中判断变量为空的几种方法小结
2013/11/12 PHP
PHP实现将textarea的值根据回车换行拆分至数组
2015/06/10 PHP
php正则提取html图片(img)src地址与任意属性的方法
2017/02/08 PHP
PHP模版引擎原理、定义与用法实例
2019/03/29 PHP
两个JavaScript jsFiddle JSBin在线调试器
2010/03/14 Javascript
JavaScript判断一个字符串是否包含指定子字符串的方法
2015/03/18 Javascript
JS使用oumousemove和oumouseout动态改变图片显示的方法
2015/03/31 Javascript
Ext JS框架中日期函数的用法及日期选择控件的实现
2016/05/21 Javascript
Javascript随机标签云代码实例
2016/06/21 Javascript
详解nodejs微信公众号开发——5.素材管理接口
2017/04/11 NodeJs
JS实现多级菜单中当前菜单不随页面跳转样式而发生变化
2017/05/30 Javascript
select自定义小三角样式代码(实用总结)
2017/08/18 Javascript
基于nodejs的雪碧图制作工具的示例代码
2018/11/05 NodeJs
详解在create-react-app使用less与antd按需加载
2018/12/06 Javascript
JS变量提升原理与用法实例浅析
2020/05/22 Javascript
[01:05:59]Mineski vs Secret 2019国际邀请赛淘汰赛 败者组 BO3 第二场 8.22
2019/09/05 DOTA
Pyramid Mako模板引入helper对象的步骤方法
2013/11/27 Python
python中日期和时间格式化输出的方法小结
2015/03/19 Python
使用Python的urllib和urllib2模块制作爬虫的实例教程
2016/01/20 Python
python类中super()和__init__()的区别
2016/10/18 Python
浅谈python中的正则表达式(re模块)
2017/10/17 Python
python里使用正则的findall函数的实例详解
2017/10/19 Python
python样条插值的实现代码
2018/12/17 Python
Python3.5 + sklearn利用SVM自动识别字母验证码方法示例
2019/05/10 Python
python创建属于自己的单词词库 便于背单词
2019/07/30 Python
Python笔记之观察者模式
2019/11/20 Python
从训练好的tensorflow模型中打印训练变量实例
2020/01/20 Python
pytorch实现Tensor变量之间的转换
2020/02/17 Python
python爬取微博评论的实例讲解
2021/01/15 Python
html5 video全屏播放/自动播放的实现示例
2020/08/06 HTML / CSS
加拿大著名的奢侈品购物网站:SSENSE(支持中文)
2020/06/25 全球购物
大学学习个人的自我评价
2014/02/18 职场文书
中国梦演讲稿范文
2014/08/28 职场文书
动画《朋友游戏》公开佐藤友生绘制的开播纪念绘
2022/04/06 日漫
Android RecyclerView实现九宫格效果
2022/06/28 Java/Android