浅析Python迭代器的高级用法


Posted in Python onJuly 16, 2020

跳过开头

首先是跳过开始部分,这个在我们读取文本的时候最常用。在实际的应用当中,比如记录的日志或者是代码等等,一般来说头部都会附上一段说明,或者用注释标注或者是用特殊的符号标记。这些信息是给用到数据的程序员看的,当我们通过代码获取数据的时候,显然是希望可以过滤掉这些信息的。

比如我们有一段数据,它的开头用#做了一些注释:

# This is a data for student
# Rows 100

xiaoming, 17, 99;
xiaoli, 18, 98;
...

常规操作当中,我们会创建一个打开文件的迭代器,我们通过遍历这个迭代器去获取文件当中的数据:

with open('xxxx.txt') as f:
  for line in f:
    print(line)

如果只是用来输出还好,如果我们需要加工文件当中的数据,那么头部的注释信息就会干扰我们代码的运行。我们当然可以手动加入一些判断,但是这会比较麻烦,代码也不够美观。针对这个问题,一个比较好的解决方案是dropwhile。

dropwhile是itemtools当中的一个函数,它可以接收一个我们自定义的过滤函数和迭代器重新生成一个新的迭代器,这个新的迭代器当中会过滤掉之前迭代器头部不符合我们要求的数据:

在刚才的例子当中我们想要过滤掉头部加了#注释的部分,我们可以这么操作:

from itertools import dropwhile
with open('xxxx.txt') as f:
  for line in dropwhile(lambda line: line.startswith('#'), f):
    print(line)

这样出来的结果就没有头部我们不需要的内容了。

当我们知道头部不符合情况的数据的格式的时候,可以使用dropwhile来规定过滤的格式。如果我们知道需要过滤的条数,则可以使用另外一个工具,叫做islice,它的本质是一个切片函数,就像是Python当中数组的切片功能一样,可以切出迭代器当中指定片段的数据。

举个例子:

from itertools import dropwhile
with open('xxxx.txt') as f:
  for line in islice(f, 3, None):
    print(line)

这样我们就会从第三行开始获取,之前的数据会被过滤掉。它其实就代表着数组当中[3: ]的切片操作。

迭代排列组合

我们都知道在C++当中有一个叫做next_permutation的函数,可以传入一个数组,返回下一个字典序的排列。在Python当中也有同样的功能,但是是以迭代器的形式使用的。

举个简单的例子,比如我们有a, b, c三个元素,我们希望求出它的所有排列:

items = ['a', 'b', 'c']
from itertools import permutations

for p in permutations(items):
  print(p)

permutations还支持多传一个参数,比如上述的排列当中我们希望只保留前两个元素,除了切片之外,我们只需要多传一个参数就好了,like this:

for p in permutations(items, 2):
  print(p)

除了排列之外,itertools当中还支持组合,用法还是一样,只是把函数名称换成是combinations而已:

from itertools import combindations
for c in combinations(items):
  print(c)

在一般的组合当中,一个元素一旦被选中那么它接下来就会从候选集当中移除,再也不会被选中。如果我们希望获得有放回的组合,我们可以再换一个函数,这个函数名称有点长,但是名字倒也直观叫做combinations_with_replacement。但既然是有放回的抽样,我们需要设定元素的数量,否则抽样可以无限进行下去。

for c in combinations_with_replacement(items, 3):
  print(c)

迭代合并后的序列

上一篇文章当中我们介绍了zip可以同时迭代多个迭代器,除此之外还有一种情况是我们需要把多个迭代器串起来迭代。比如系统的日志打在了多个文件当中,我们希望找出其中有error的日志来分析。这个时候,我们希望的不是同时读取多个迭代器,而是希望能够有办法将多个迭代器的内容串联起来。这个功能就是itertools当中的chain方法,它接受多个迭代器,当我们遍历的时候,会自动将多个迭代器的内容串联起来,我们可以无缝迭代。

举个例子:

from itertools import chain
nums = [1, 2, 3]
chars = ['a', 'b', 'c']

for i in chain(nums, chars):
  print(i)

这样我们会把nums和chars当中的内容一起输出出来,就好像从头到尾只执行了一个迭代器一样

你可能会说我们不用chain也可以实现啊,我们可以这样:

for i in nums + chars:
  print(i)

的确,从结果上来看这样也是行得通的。但是如果我们分析一下内部执行的时候的中间变量,会发现当我们执行nums+chars的时候,实际上是先创建了一个新的临时list。然后在这个list当中存储nums和chars的数据,也就是说我们迭代的其实是这个新的list。这带来的结果是我们额外开辟了一段内存,并且花费了一些时间。如果我们使用chain,它并不会有这样的中间变量,完全是通过迭代器来执行的迭代,非常节省内存,这也是chain的优点。

归并迭代的内容

对于归并操作我们应该都不陌生,在之前的归并排序以及一些题解的文章当中我们见过很多次。同样,我们在使用工具合并多个迭代器内容的时候,如果迭代器当中的内容有序,我们也可以对多个迭代器当中的元素进行归并,而不再需要我们自己手动操作。

使用我们之前介绍的heapq的库可以非常轻松地做到这一点,我们一起来看一个例子:

a = [1, 3, 5]
b = [2, 4, 6]

import heapq

for c in heapq.merge(a, b):
  print(c)

执行之后,我们会得到[1, 2, 3, 4, 5, 6]的结果。也就是说通过heapq.merge操作,我们把多个有序的迭代器合并到了一起。当然我们也可以自己合并,但如果我们只是需要利用当中的数据的话,使用merge操作可以节省内存空间。

到这里内容就结束了,本文和之前的文章基本上列举完了常用的迭代器用法。当然,除了上述讲到的内容之外,Python当中的迭代器还有一些其他的用法,不过相对不太常用,感兴趣的同学可以私下了解。

以上就是浅析Python迭代器的高级用法的详细内容,更多关于Python迭代器的高级用法的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python ORM框架SQLAlchemy学习笔记之映射类使用实例和Session会话介绍
Jun 10 Python
python2.7+selenium2实现淘宝滑块自动认证功能
Feb 24 Python
利用python将pdf输出为txt的实例讲解
Apr 23 Python
[机器视觉]使用python自动识别验证码详解
May 16 Python
python设置环境变量的作用和实例
Jul 09 Python
详解python实现数据归一化处理的方式:(0,1)标准化
Jul 17 Python
python base64库给用户名或密码加密的流程
Jan 02 Python
python实现从尾到头打印单链表操作示例
Feb 22 Python
Django自定义列表 models字段显示方式
Apr 03 Python
PyCharm2019 安装和配置教程详解附激活码
Jul 31 Python
教你如何用python操作摄像头以及对视频流的处理
Oct 12 Python
Django 用户认证Auth组件的使用
Nov 30 Python
python 使用递归的方式实现语义图片分割功能
Jul 16 #Python
Django serializer优化类视图的实现示例
Jul 16 #Python
python中plt.imshow与cv2.imshow显示颜色问题
Jul 16 #Python
Python实现GIF图倒放
Jul 16 #Python
浅谈python处理json和redis hash的坑
Jul 16 #Python
Python requests及aiohttp速度对比代码实例
Jul 16 #Python
Python3 搭建Qt5 环境的方法示例
Jul 16 #Python
You might like
全国FM电台频率大全 - 19 广东省
2020/03/11 无线电
从网上搜到的phpwind 0day的代码
2006/12/07 PHP
简单采集了yahoo的一些数据
2007/02/14 PHP
php模板中出现空行解决方法
2011/03/08 PHP
php学习之数据类型之间的转换介绍
2011/06/09 PHP
PHP的password_hash()使用实例
2014/03/17 PHP
PHP实现Google plus的好友拖拽分组效果
2016/10/21 PHP
thinkphp5.0自定义验证规则使用方法
2017/11/16 PHP
一个原生的用户等级的进度条
2010/07/03 Javascript
Js 弹出框口并返回值的两种常用方法
2010/12/30 Javascript
JavaScript返回当前会话cookie全部键值对照的方法
2015/04/03 Javascript
javascript实现checkbox全选的代码
2015/04/30 Javascript
详解Jquery实现ready和bind事件
2016/04/14 Javascript
前端面试题及答案整理(二)
2016/08/26 Javascript
jQuery validate插件功能与用法详解
2016/12/15 Javascript
基于vue-cli 打包时抽离项目相关配置文件详解
2018/03/07 Javascript
mpvue构建小程序的方法(步骤+地址)
2018/05/22 Javascript
Vue 组件注册实例详解
2019/02/23 Javascript
JS实现处理时间,年月日,星期的公共方法示例
2019/05/31 Javascript
vue 路由守卫(导航守卫)及其具体使用
2020/02/25 Javascript
JavaScript字符和ASCII实现互相转换
2020/06/03 Javascript
[01:23:24]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Elephant BO3 第三场 2月7日
2021/03/11 DOTA
在Mac OS上使用mod_wsgi连接Python与Apache服务器
2015/12/24 Python
Python实现将一个大文件按段落分隔为多个小文件的简单操作方法
2017/04/17 Python
python实现人人自动回复、抢沙发功能
2018/06/08 Python
python 直接赋值和copy的区别详解
2019/08/07 Python
Kears+Opencv实现简单人脸识别
2019/08/28 Python
python中列表的含义及用法
2020/05/26 Python
css3实现3d旋转动画特效
2015/03/10 HTML / CSS
艾滋病宣传活动总结
2014/05/08 职场文书
房地产推广策划方案
2014/05/19 职场文书
2014小学生国庆65周年演讲稿
2014/09/21 职场文书
2015年八一建军节演讲稿
2015/03/19 职场文书
商场收银员岗位职责
2015/04/07 职场文书
2015年街道办事处团委工作总结
2015/10/14 职场文书
python文件名批量重命名脚本实例代码
2021/04/22 Python