浅析Python迭代器的高级用法

跳过开头

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

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

# 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迭代器的高级用法的资料请关注我们其它相关文章!

(0)

相关推荐

  • Python迭代器协议及for循环工作机制详解

    一.递归与迭代 二.什么是迭代器协议 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个stopiteration异常,已终止迭代(只能往后走不能往前退) 2.可迭代对象:实现了迭代器协议的对象(如何实现:对象内部定义一个__iter__()方法) 3.协议是一种约定,可迭代对象实现了迭代器协议,python的内部工具(如for循环,sum,min,max函数等)使用迭代器协议访问对象. 三.python中强大的for循环机制 for循环的本质:循

  • 浅谈Python中的生成器和迭代器

    迭代器 迭代器协议 对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么返回一个异常来终止本次迭代.(只能往前走,不能往后退!) 迭代器对象 遵循了(实现了)迭代器协议的对象.(对象内部实现了一个__next__方法,以实现迭代器协议)称为一个迭代器对象.他们的作用是逐个遍历容器中的对象.迭代器对象一定是可迭代对象 >>> from collections import Iterable, Iterator >>> l = list([1,2,3]) #

  • Python中的迭代器与生成器高级用法解析

    迭代器 迭代器是依附于迭代协议的对象--基本意味它有一个next方法(method),当调用时,返回序列中的下一个项目.当无项目可返回时,引发(raise)StopIteration异常. 迭代对象允许一次循环.它保留单次迭代的状态(位置),或从另一个角度讲,每次循环序列都需要一个迭代对象.这意味我们可以同时迭代同一个序列不只一次.将迭代逻辑和序列分离使我们有更多的迭代方式. 调用一个容器(container)的__iter__方法创建迭代对象是掌握迭代器最直接的方式.iter函数为我们节约一些

  • 详解python中的生成器、迭代器、闭包、装饰器

    迭代是访问集合元素的一种方式.迭代器是一个可以记住遍历的位置的对象.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退. 1|1可迭代对象 以直接作用于 for 循环的数据类型有以下几种: 一类是集合数据类型,如 list . tuple . dict . set . str 等: 一类是 generator ,包括生成器和带 yield 的generator function. 这些可以直接作用于 for 循环的对象统称为可迭代对象: Iterable .

  • Python函数的迭代器与生成器的示例代码

    函数的迭代器 函数的强大功能叫做迭代器,Python里面最具威力的功能之一.迭代器我们听起来会感觉非常陌生,在list.tuple都有用到它,我们是使用for和in取列表中的每一个元素,对每个元素依次处理,这种方法就叫做迭代,实现这种方法的函数叫做迭代器.迭代器中有两个基本的函数,这个函数叫做方法,这个是面向对象编程称呼的一个方法,这两个方法叫做iter()和next(). 1.什么是迭代?迭代是一个重复的过程,并且每次重复都是基于上一次的结果而来 2.要想了解迭代器到底是什么?必须先了解一个概

  • 实例讲解Python 迭代器与生成器

    迭代器 迭代是Python最强大的功能之一,是访问集合元素的一种方式. 迭代器是一个可以记住遍历的位置的对象. 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退. 迭代器有两个基本的方法:iter() 和 next(). 字符串,列表或元组对象都可用于创建迭代器: >>> list=[1,2,3,4] >>> it = iter(list) # 创建迭代器对象 >>> print (next(it)) # 输出迭

  • python 生成器和迭代器的原理解析

    一.生成器简介 在python中,生成器是根据某种算法边循环边计算的一种机制.主要就是用于操作大量数据的时候,一般我们会将操作的数据读入内存中处理,可以计算机的内存是比较宝贵的资源,我认为的当要处理的数据超过内存四分之一的大小时就应该使用生成器. 二.生成器有什么特点? 1.和传统的容器相比,生成器更节省内存. 2.延迟计算,在我们需要结果时就调用一下生成器的next()方法即可. 3.可迭代,你可以像遍历list一样,遍历生成器 三.如何创建生成器? 在python中有两种方式创建生成器:生成

  • 浅析Python迭代器的高级用法

    跳过开头 首先是跳过开始部分,这个在我们读取文本的时候最常用.在实际的应用当中,比如记录的日志或者是代码等等,一般来说头部都会附上一段说明,或者用注释标注或者是用特殊的符号标记.这些信息是给用到数据的程序员看的,当我们通过代码获取数据的时候,显然是希望可以过滤掉这些信息的. 比如我们有一段数据,它的开头用#做了一些注释: # This is a data for student # Rows 100 xiaoming, 17, 99; xiaoli, 18, 98; ... 常规操作当中,我们会

  • Python tkinter事件高级用法实例

    本文实例讲述了Python tkinter事件高级用法.分享给大家供大家参考,具体如下: 先来看看运行效果: 完整实例代码: # -*- coding:utf-8-*- #! python3 from tkinter import * import threading, time trace = 0 class CanvasEventsDemo: def __init__(self, parent=None): canvas = Canvas(width=300, height=300, bg=

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

    本文实例讲述了Python迭代器与生成器用法.分享给大家供大家参考,具体如下: 迭代器,迭代的工具 什么是迭代器? 指的是一个重复的过程,每一次重复称为一次迭代,并且每一次重复的结果是下一次重复的初始值 l=['a','b','c'] count=0 while count <len(l): print(l[count]) count+=1 为什么要有迭代器 1.对于序列类型:str,list,tuple,可以依赖索引来迭代取值 2.对于dict,set,文件,python必须为我们提供一种不依

  • 浅析python中的del用法

    del是python关键字,就像def.and.or一样.它不是字典.列表的方法,但是可以用来删除字典.列表的元素. python中的del用法比较特殊,新手学习往往产生误解,弄清del的用法,可以帮助深入理解python的内存方面的问题. python的del不同于C的free和C++的delete. 由于python都是引用,而python有GC机制,所以,del语句作用在变量上,而不是数据对象上. if __name__=='__main__': a=1 # 对象 1 被 变量a引用,对象

  • Python进阶之高级用法详细总结

    一.Lambda表达式 Lambda表达式又被称之为匿名函数 格式 lambda 参数列表:函数体 def add(x,y): return x+y print(add(3,4)) #上面的函数可以写成Lambda函数 add_lambda=lambda x,y:x+y add_lambda(3,4) 二.map函数 函数就是有输入和输出,map的输入和输出对应关系如下图所示: 就是要把一个可迭代的对象按某个规则映射到新的对象上. 因此map函数要有两个参数,一个是映射规则,一个是可迭代对象.

  • Python 正则表达式的高级用法

    对于Python来说,学习正则就要学习模块re的使用方法.本文将展示一些大家都应该掌握的高级技巧. 编译正则对象 re.compile函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象.该对象拥有一系列方法用于正则表达式匹配和替换.用法上略有区别,举个例子, 匹配一个字符串可用如下方式: 如果使用compile,将变成: 为什么要这么用呢?其实就是为了提高正则匹配的速度,重复利用正则表达式对象.我们对比一下2种方式的效率: 可以看到第二种方式要快很多.在实际的工作中你会发现越多的使用编

  • python迭代器实例简析

    本文实例讲述了python迭代器的简单用法,分享给大家供大家参考.具体分析如下: 生成器表达式是用来生成函数调用时序列参数的一种迭代器写法 生成器对象可以遍历或转化为列表(或元组等数据结构),但不能切片(slicing).当函数的唯一的实参是可迭代序列时,便可以去掉生成器表达式两端>的圆括号,写出更优雅的代码: >>>> sum(i for i in xrange(10)) 45 sum声明: sum(iterable[, start]) Sums start and the

  • Python高级用法总结

    列表推导(list comprehensions) 场景1:将一个三维列表中所有一维数据为a的元素合并,组成新的二维列表. 最简单的方法:新建列表,遍历原三维列表,判断一维数据是否为a,若为a,则将该元素append至新列表中. 缺点:代码太繁琐,对于Python而言,执行速度会变慢很多. 针对场景1,我们首先应该想到用列表解析式来解决处理,一行代码即可解决: lista = [item for item in array if item[0] == 'a'] 那么,何为列表解析式? 官方解释:

  • python中的内置函数max()和min()及mas()函数的高级用法

    max(iterable, *[, key, default]) max(arg1, arg2, *args[, key]) 函数功能为取传入的多个参数中的最大值,或者传入的可迭代对象元素中的最大值.默认数值型参数,取值大者:字符型参数,取字母表排序靠后者.还可以传入命名参数key,其为一个函数,用来指定取最大值的方法.default命名参数用来指定最大值不存在时返回的默认值. eg a.传入的多个参数的最大值 print(max(1,2,3,4)) 输出 b.1 传入可迭代对象时,取其元素最大

  • Python迭代器定义与简单用法分析

    本文实例讲述了Python迭代器定义与简单用法.分享给大家供大家参考,具体如下: 一.什么是迭代器 迭代,顾名思义就是重复做一些事很多次(就现在循环中做的那样).迭代器是实现了__next__()方法的对象(这个方法在调用时不需要任何参数),它是访问可迭代序列的一种方式,通常其从序列的第一个元素开始访问,直到所有的元素都被访问才结束. [注意]:迭代器只能前进不能后退 [迭代器的优点]: 使用迭代器不要求事先准备好整个迭代过程中的所有元素.迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之

随机推荐