Python 中迭代器与生成器实例详解

Python 中迭代器与生成器实例详解

本文通过针对不同应用场景及其解决方案的方式,总结了Python中迭代器与生成器的一些相关知识,具体如下:

1.手动遍历迭代器

应用场景:想遍历一个可迭代对象中的所有元素,但是不想用for循环

解决方案:使用next()函数,并捕获StopIteration异常

def manual_iter():
  with open('/etc/passwd') as f:
    try:
      while True:
        line=next(f)
        if line is None:
          break
        print(line,end='')
      except StopIteration:
        pass
#test case
items=[1,2,3]
it=iter(items)
next(it)
next(it)
next(it)

2.代理迭代

应用场景:想直接在一个包含有列表、元组或其他可迭代对象的容器对象上执行迭代操作

解决方案:定义一个iter()方法,将迭代操作代理到容器内部的对象上

示例:

class Node:
  def __init__(self,value):
    self._value=value
    self._children=[]
  def __repr__(self):
    return 'Node({!r})'.fromat(self._value)
  def add_child(self,node):
    self._children.append(node)
  def __iter__(self):
    #将迭代请求传递给内部的_children属性
    return iter(self._children)
#test case
if __name='__main__':
  root=Node(0)
  child1=Node(1)
  child2=Nide(2)
  root.add_child(child1)
  root.add_child(child2)
  for ch in root:
    print(ch)

3.反向迭代

应用场景:想要反向迭代一个序列

解决方案:使用内置的reversed()函数或者在自定义类上实现reversed()

示例1

a=[1,2,3,4]
for x in reversed(a):
  print(x) #4 3 2 1

f=open('somefile')
for line in reversed(list(f)):
  print(line,end='')
#test case
for rr in reversed(Countdown(30)):
  print(rr)

for rr in Countdown(30):
  print(rr)

示例2

class Countdown:
  def __init__(self,start):
    self.start=start
  #常规迭代
  def __iter__(self):
    n=self.start
    while n > 0:
      yield n
      n -= 1
  #反向迭代
  def __reversed__(self):
    n=1
    while n <= self.start:
      yield n
      n +=1

4.有选择的迭代

应用场景:想遍历一个可迭代对象,但是对它开始的某些元素并不感兴趣,想跳过

解决方案:使用itertools.dropwhile()

示例1

with open('/etc/passwd') as f:
  for line in f:
    print(line,end='')

示例2

from itertools import dropwhile
with open('/etc/passwd') as f:
  for line in dropwhile(lambda line:line.startwith('#'),f):
    print(line,end='')

5.同时迭代多个序列

应用场景:想同时迭代多个序列每次分别从一个序列中取一个元素

解决方案:使用zip()函数

6.不同集合上元素的迭代

应用场景:想在多个对象执行相同的操作,但是这些对象在不同的容器中

解决方案:使用itertool.chain()函数

7.展开嵌套的序列

应用场景:想将一个多层嵌套的序列展开成一个单层列表

解决方案:使用包含yield from语句的递归生成器

示例

from collections import Iterable
def flatten(items,ignore_types=(str,bytes)):
  for x in items:
    if isinstance(x,Iterable) and not isinstance(x,ignore_types):
      yield from flatten(x)
    else:
      yield x
#test case
items=[1,2,[3,4,[5,6],7],8]
for x in flatten(items):
  print(x)

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

时间: 2017-03-26

Python 迭代器与生成器实例详解

Python 迭代器与生成器实例详解 一.如何实现可迭代对象和迭代器对象 1.由可迭代对象得到迭代器对象 例如l就是可迭代对象,iter(l)是迭代器对象 In [1]: l = [1,2,3,4] In [2]: l.__iter__ Out[2]: <method-wrapper '__iter__' of list object at 0x000000000426C7C8> In [3]: t = iter(l) In [4]: t.next() Out[4]: 1 In [5]: t.

举例讲解Python中的迭代器、生成器与列表解析用法

迭代器:初探 上一章曾经提到过,其实for循环是可用于任何可迭代的对象上的.实际上,对Python中所有会从左至右扫描对象的迭代工具而言都是如此,这些迭代工具包括了for循环.列表解析.in成员关系测试以及map内置函数等. "可迭代对象"的概念在Python中是相当新颖的,基本这就是序列观念的通用化:如果对象时实际保存的序列,或者可以再迭代工具环境中一次产生一个结果的对象,那就看做是可迭代的. >>文件迭代器 作为内置数据类型的文件也是可迭代的,它有一个名为__next_

详解Python的迭代器、生成器以及相关的itertools包

对数学家来说,Python这门语言有着很多吸引他们的地方.举几个例子:对于tuple.lists以及sets等容器的支持,使用与传统数学类似的符号标记方式,还有列表推导式这样与数学中集合推导式和集的结构式(set-builder notation)很相似的语法结构. 另外一些很吸引数学爱好者的特性是Python中的iterator(迭代器).generator(生成器)以及相关的itertools包.这些工具帮助人们能够很轻松的写出处理诸如无穷序列(infinite sequence).随机过程

python的迭代器与生成器实例详解

本文以实例详解了python的迭代器与生成器,具体如下所示: 1. 迭代器概述:   迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退.   1.1 使用迭代器的优点   对于原生支持随机访问的数据结构(如tuple.list),迭代器和经典for循环的索引访问相比并无优势,反而丢失了索引值(可以使用内建函数enumerate()找回这个索引值).但对于无法随机访问的数据结构(比

python迭代器与生成器详解

例子 老规矩,先上一个代码: def add(s, x): return s + x def gen(): for i in range(4): yield i base = gen() for n in [1, 10]: base = (add(i, n) for i in base) print list(base) 这个东西输出可以脑补一下, 结果是[20,21,22,23], 而不是[10, 11, 12, 13]. 当时纠结了半天,一直没搞懂,后来齐老师稍微指点了一下, 突然想明白了-

Python迭代器和生成器介绍

迭代器 迭代器是一个实现了迭代器协议的对象,Python中的迭代器协议就是有next方法的对象会前进到下一结果,而在一系列结果的末尾是,则会引发StopIteration. 在for循环中,Python将自动调用工厂函数iter()获得迭代器,自动调用next()获取元素,还完成了检查StopIteration异常的工作. 常用的几个内建数据结构tuple.list.set.dict都支持迭代器,字符串也可以使用迭代操作. 你也可以自己实现一个迭代器,如上所述,只需要在类的__iter__方法中

深入讲解Python中的迭代器和生成器

在Python中,很多对象都是可以通过for语句来直接遍历的,例如list.string.dict等等,这些对象都可以被称为可迭代对象.至于说哪些对象是可以被迭代访问的,就要了解一下迭代器相关的知识了. 迭代器 迭代器对象要求支持迭代器协议的对象,在Python中,支持迭代器协议就是实现对象的__iter__()和next()方法.其中__iter__()方法返回迭代器对象本身:next()方法返回容器的下一个元素,在结尾时引发StopIteration异常. __iter__()和next()

Python的迭代器和生成器使用实例

一.迭代器Iterators 迭代器仅是一容器对象,它实现了迭代器协议.它有两个基本方法: 1)next方法 返回容器的下一个元素 2)__iter__方法 返回迭代器自身 迭代器可使用内建的iter方法创建,见例子: 复制代码 代码如下: >>> i = iter('abc') >>> i.next() 'a' >>> i.next() 'b' >>> i.next() 'c' >>> i.next() Trace

Python的迭代器和生成器

先说迭代器,对于string.list.dict.tuple等这类容器对象,使用for循环遍历是很方便的.在后台for语句对容器对象调用iter()函数,iter()是python的内置函数.iter()会返回一个定义了next()方法的迭代器对象,它在容器中逐个访问容器内元素,next()也是python的内置函数.在没有后续元素时,next()会抛出一个StopIteration异常,通知for语句循环结束.比如: >>> s = 'abc' >>> it = it

解析Python中的生成器及其与迭代器的差异

生成器 生成器是一种迭代器,是一种特殊的函数,使用yield操作将函数构造成迭代器.普通的函数有一个入口,有一个返回值:当函数被调用时,从入口开始执行,结束时返回相应的返回值.生成器定义的函数,有多个入口和多个返回值:对生成器执行next()操作,进行生成器的入口开始执行代码,yield操作向调用者返回一个值,并将函数挂起:挂起时,函数执行的环境和参数被保存下来:对生成器执行另一个next()操作时,参数从挂起状态被重新调用,进入上次挂起的执行环境继续下面的操作,到下一个yield操作时重复上面

一篇文章彻底搞懂Python中可迭代(Iterable)、迭代器(Iterator)与生成器(Generator)的概念

前言 在Python中可迭代(Iterable).迭代器(Iterator)和生成器(Generator)这几个概念是经常用到的,初学时对这几个概念也是经常混淆,现在是时候把这几个概念搞清楚了. 0x00 可迭代(Iterable) 简单的说,一个对象(在Python里面一切都是对象)只要实现了只要实现了__iter__()方法,那么用isinstance()函数检查就是Iterable对象: 例如 class IterObj: def __iter__(self): # 这里简单地返回自身 #

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

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

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

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

解析python 中/ 和 % 和 //(地板除)

python / 和 % 和 //(地板除)用于对数据进行除法运算. python中 // 和 / 和 % 简介 python中与除法相关的三个运算符是// 和 / 和 %,下面逐一介绍. "/",这是传统的除法,3/2=1.5 "//",在python中,这个叫"地板除",3//2=1 "%",这个是取模操作,也就是区余数,4%2=0,5%2=1 Python中分为3种除法:1./,2.%,3.//. 1./ 基于 pyth

简单理解Python中基于生成器的状态机

简单生成器有许多优点.生成器除了能够用更自然的方法表达一类问题的流程之外,还极大地改善了许多效率不足之处.在 Python 中,函数调用代价不菲:除其它因素外,还要花一段时间解决函数参数列表(除了其它的事情外,还要分析位置参数和缺省参数).初始化框架对象还要采取一些建立步骤(据 Tim Peters 在 comp.lang.python 上所说,有 100 多行 C 语言程序:我自己还没检查 Python 源代码呢).与此相反,恢复一个生成器就相当省力:参数已经解析完了,而且框架对象正"无所事事

Python中的生成器和yield详细介绍

列表推导与生成器表达式 当我们创建了一个列表的时候,就创建了一个可以迭代的对象: 复制代码 代码如下: >>> squares=[n*n for n in range(3)] >>> for i in squares:  print i   0 1 4 这种创建列表的操作很常见,称为列表推导.但是像列表这样的迭代器,比如str.file等,虽然用起来很方便,但有一点,它们是储存在内存中的,如果值很大,会很麻烦. 而生成器表达式不同,它执行的计算与列表包含相同,但会迭代的

深入解析Python中的list列表及其切片和迭代操作

有序列表list >>> listTest = ['ha','test','yes'] >>> listTest ['ha', 'test', 'yes'] len()获取list元素个数. >>> len(listTest) 3 可以用索引来访问每一个元素,0表示第一个,-1还可以表示最后一个,即倒数第一个,依此类推-2表示倒数第二个,超过了也会报越界错误. >>> listTest[0] 'ha' >>> lis

深入解析Python中函数的参数与作用域

传递参数 函数传递参数时的一些简要的关键点: 参数的传递是通过自动将对象赋值给本地变量名来实现的.所有的参数实际上都是通过指针进行传递的,作为参数被传递的对象从来不自动拷贝. 在函数内部的参数名的赋值不会影响调用者. 改变函数的可变对象参数的值会对调用者有影响. 实际上,Python的参数传递模型和C语言的相当相似: 不可变参数"通过值"进行传递.像整数和字符串这样的对象是通过对象引用而不是拷贝进行的,但是因为不论怎么样都不可能在原处改变不可变对象,实际的效果就很像创建了一份拷贝. 可

深入解析Python中的lambda表达式的用法

普通的数学运算用这个纯抽象的符号演算来定义,计算结果只能在脑子里存在.所以写了点代码,来验证文章中介绍的演算规则. 我们来验证文章里介绍的自然数及自然数运算规则.说到自然数,今天还百度了一下,据度娘说,1993年后国家规定0是属于自然数.先定义自然数及自然数的运算规则: 用lambda表达式定义自然数(邱齐数) 0 := λf.λx.x 1 := λf.λx.f x 2 := λf.λx.f (f x) 3 := λf.λx.f (f (f x)) ... 上面定义直观的意思就是数字n, 是f(