时间:2021-05-22
跳过开头
首先是跳过开始部分,这个在我们读取文本的时候最常用。在实际的应用当中,比如记录的日志或者是代码等等,一般来说头部都会附上一段说明,或者用注释标注或者是用特殊的符号标记。这些信息是给用到数据的程序员看的,当我们通过代码获取数据的时候,显然是希望可以过滤掉这些信息的。
比如我们有一段数据,它的开头用#做了一些注释:
# This is a data for student# Rows 100xiaoming, 17, 99;xiaoli, 18, 98;...常规操作当中,我们会创建一个打开文件的迭代器,我们通过遍历这个迭代器去获取文件当中的数据:
with open('xxxx.txt') as f: for line in f: print(line)如果只是用来输出还好,如果我们需要加工文件当中的数据,那么头部的注释信息就会干扰我们代码的运行。我们当然可以手动加入一些判断,但是这会比较麻烦,代码也不够美观。针对这个问题,一个比较好的解决方案是dropwhile。
dropwhile是itemtools当中的一个函数,它可以接收一个我们自定义的过滤函数和迭代器重新生成一个新的迭代器,这个新的迭代器当中会过滤掉之前迭代器头部不符合我们要求的数据:
在刚才的例子当中我们想要过滤掉头部加了#注释的部分,我们可以这么操作:
from itertools import dropwhilewith open('xxxx.txt') as f: for line in dropwhile(lambda line: line.startswith('#'), f): print(line)这样出来的结果就没有头部我们不需要的内容了。
当我们知道头部不符合情况的数据的格式的时候,可以使用dropwhile来规定过滤的格式。如果我们知道需要过滤的条数,则可以使用另外一个工具,叫做islice,它的本质是一个切片函数,就像是Python当中数组的切片功能一样,可以切出迭代器当中指定片段的数据。
举个例子:
from itertools import dropwhilewith 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 permutationsfor p in permutations(items): print(p)permutations还支持多传一个参数,比如上述的排列当中我们希望只保留前两个元素,除了切片之外,我们只需要多传一个参数就好了,like this:
for p in permutations(items, 2): print(p)除了排列之外,itertools当中还支持组合,用法还是一样,只是把函数名称换成是combinations而已:
from itertools import combindationsfor 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 chainnums = [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 heapqfor c in heapq.merge(a, b): print(c)执行之后,我们会得到[1, 2, 3, 4, 5, 6]的结果。也就是说通过heapq.merge操作,我们把多个有序的迭代器合并到了一起。当然我们也可以自己合并,但如果我们只是需要利用当中的数据的话,使用merge操作可以节省内存空间。
到这里内容就结束了,本文和之前的文章基本上列举完了常用的迭代器用法。当然,除了上述讲到的内容之外,Python当中的迭代器还有一些其他的用法,不过相对不太常用,感兴趣的同学可以私下了解。
以上就是浅析Python迭代器的高级用法的详细内容,更多关于Python迭代器的高级用法的资料请关注其它相关文章!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
本文实例讲述了python中迭代器(iterator)用法。分享给大家供大家参考。具体如下:#---------------------------------
本文实例讲述了Python设计模式之迭代器模式原理与用法。分享给大家供大家参考,具体如下:迭代器模式(IteratorPattern):提供方法顺序访问一个聚合
本文实例讲述了Python学习笔记之迭代器和生成器用法。分享给大家供大家参考,具体如下:迭代器和生成器迭代器每次可以返回一个对象元素的对象,例如返回一个列表。我
Python3的可迭代解包在PEP3132-ExtendedIterableUnpacking里面描述了一种对可迭代对象的解包用法,Python3可用:In:a
本文实例讲述了python生成器用法。分享给大家供大家参考,具体如下:1.生成器利用迭代器,我们可以在每次迭代获取数据(通过next()方法)时按照特定的规律进