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 相关文章推荐
python中xrange和range的区别
May 13 Python
利用pyinstaller或virtualenv将python程序打包详解
Mar 22 Python
python文件特定行插入和替换实例详解
Jul 12 Python
解决Spyder中图片显示太小的问题
Apr 27 Python
Python生成指定数量的优惠码实操内容
Jun 18 Python
django rest framework vue 实现用户登录详解
Jul 29 Python
Python帮你微信头像任意添加装饰别再@微信官方了
Sep 25 Python
PyCharm2019安装教程及其使用(图文教程)
Sep 29 Python
Python中的引用和拷贝实例解析
Nov 14 Python
python 字典访问的三种方法小结
Dec 05 Python
使用Python获取当前工作目录和执行命令的位置
Mar 09 Python
Python StringIO及BytesIO包使用方法解析
Jun 15 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
phpMyAdmin 安装配置方法和问题解决
2009/06/08 PHP
解析php curl_setopt 函数的相关应用及介绍
2013/06/17 PHP
基于PHP服务端图片生成缩略图的方法详解
2013/06/20 PHP
Smarty实现页面静态化(生成HTML)的方法
2016/05/23 PHP
PHP fopen函数用法实例讲解
2019/02/15 PHP
将HTML自动转为JS代码
2006/06/26 Javascript
javascript编写贪吃蛇游戏
2015/07/07 Javascript
AngularJS 模型详细介绍及实例代码
2016/07/27 Javascript
利用JS判断鼠标移入元素的方向
2016/12/11 Javascript
微信小程序之页面跳转和参数传递的实现
2017/09/29 Javascript
layui.js实现的表单验证功能示例
2017/11/15 Javascript
Vue中使用vee-validate表单验证的方法
2018/05/09 Javascript
JavaScript常用工具方法封装
2019/02/12 Javascript
ES6中Set和Map用法实例详解
2020/03/02 Javascript
Vue 构造选项 - 进阶使用说明
2020/08/14 Javascript
小程序实现上传视频功能
2020/08/18 Javascript
[01:22:10]Ti4 循环赛第二日 DK vs Empire
2014/07/11 DOTA
[03:03]2014DOTA2国际邀请赛 EG战队专访
2014/07/12 DOTA
[42:04]DOTA2上海特级锦标赛主赛事日 - 2 胜者组第一轮#3Secret VS OG第一局
2016/03/03 DOTA
[02:49]DOTA2完美大师赛首日观众采访
2017/11/23 DOTA
理解python中生成器用法
2017/12/20 Python
python简单操作excle的方法
2018/09/12 Python
Python基础之函数的定义与使用示例
2019/03/23 Python
windows下numpy下载与安装图文教程
2019/04/02 Python
Python实现网页截图(PyQT5)过程解析
2019/08/12 Python
python sorted方法和列表使用解析
2019/11/18 Python
浅谈Django QuerySet对象(模型.objects)的常用方法
2020/03/28 Python
css3实现一个div设置多张背景图片及background-image属性实例演示
2017/08/10 HTML / CSS
HTML5制作表格样式
2016/11/15 HTML / CSS
荷兰在线体育用品商店:Avantisport.nl
2018/07/04 全球购物
Optimalprint加拿大:在线打印服务
2020/04/03 全球购物
旷课检讨书2000字
2014/01/14 职场文书
婚纱店策划方案
2014/05/22 职场文书
2014年文艺部工作总结
2014/11/17 职场文书
Oracle设置DB、监听和EM开机启动的方法
2021/04/25 Oracle
详解Vue slot插槽
2021/11/20 Vue.js