[转载] Python 迭代器 深入理解 与应用示例

参考链接: Python | 可迭代和迭代器之间的区别

本篇文章简单谈谈可迭代对象,迭代器和生成器之间的关系。

 

 

三者简要关系图

 

 

 

 

 

可迭代对象与迭代器

 

刚开始我认为这两者是等同的,但后来发现并不是这样;下面直接抛出结论:

1)可迭代对象包含迭代器。2)如果一个对象拥有__iter__方法,其是可迭代对象;如果一个对象拥有next方法,其是迭代器。3)定义可迭代对象,必须实现__iter__方法;定义迭代器,必须实现__iter__和next方法。

 

 

你也许会问,结论3与结论2是不是有一点矛盾?既然一个对象拥有了next方法就是迭代器,那为什么迭代器必须同时实现两方法呢?

因为结论1,迭代器也是可迭代对象,因此迭代器必须也实现__iter__方法。

 

 

介绍一下上面涉及到的两个方法:

1)__iter__()

该方法返回的是当前对象的迭代器类的实例。因为可迭代对象与迭代器都要实现这个方法,因此有以下两种写法。

写法一:用于可迭代对象类的写法,返回该可迭代对象的迭代器类的实例。

写法二:用于迭代器类的写法,直接返回self(即自己本身),表示自身即是自己的迭代器。

也许有点晕,没关系,下面会给出两写法的例子,我们结合具体例子看。

 

2)next()

 

返回迭代的每一步,实现该方法时注意要最后超出边界要抛出StopIteration异常。

 

下面举个可迭代对象与迭代器的例子:

 

 

 

  

   [python] 

   view plain

    copy

   

   

   

  

 

 #!/usr/bin/env python  # coding=utf-8      class MyList(object):            # 定义可迭代对象类        def __init__(self, num):          self.data = num          # 上边界        def __iter__(self):          return MyListIterator(self.data)  # 返回该可迭代对象的迭代器类的实例      class MyListIterator(object):    # 定义迭代器类,其是MyList可迭代对象的迭代器类        def __init__(self, data):          self.data = data         # 上边界          self.now = 0             # 当前迭代值,初始为0        def __iter__(self):          return self              # 返回该对象的迭代器类的实例;因为自己就是迭代器,所以返回self        def next(self):              # 迭代器类必须实现的方法          while self.now < self.data:              self.now += 1              return self.now - 1  # 返回当前迭代值          raise StopIteration      # 超出上边界,抛出异常      my_list = MyList(5)              # 得到一个可迭代对象  print type(my_list)              # 返回该对象的类型    my_list_iter = iter(my_list)     # 得到该对象的迭代器实例,iter函数在下面会详细解释  print type(my_list_iter)      for i in my_list:                # 迭代      print i  

 

运行结果:

 

 

问题:上面的例子中出现了iter函数,这是什么东西?和__iter__方法有关系吗?

 

其实该函数与迭代是息息相关的,通过在Python命令行中打印“help(iter)”得知其有以下两种用法。

 

 

用法一:iter(callable, sentinel)

 

不停的调用callable,直至其的返回值等于sentinel。其中的callable可以是函数,方法或实现了__call__方法的实例。

 

 

用法二:iter(collection)

 

1)用于返回collection对象的迭代器实例,这里的collection我认为表示的是可迭代对象,即该对象必须实现__iter__方法;

事实上iter函数与__iter__方法联系非常紧密,iter()是直接调用该对象的__iter__(),并把__iter__()的返回结果作为自己的返回值,故该用法常被称为“创建迭代器”。

 

2)iter函数可以显示调用,或当执行“for i in obj:”,Python解释器会在第一次迭代时自动调用iter(obj),之后的迭代会调用迭代器的next方法,for语句会自动处理最后抛出的StopIteration异常。

 

通过上面的例子,相信对可迭代对象与迭代器有了更具体的认识,那么生成器与它们有什么关系呢?下面简单谈一谈

 

 

生成器

 

生成器是一种特殊的迭代器,生成器自动实现了“迭代器协议”(即__iter__和next方法),不需要再手动实现两方法。

生成器在迭代的过程中可以改变当前迭代值,而修改普通迭代器的当前迭代值往往会发生异常,影响程序的执行。

 

看一个生成器的例子:

 

 

  

   [python] 

   view plain

    copy

   

   

   

  

 

 #!/usr/bin/env python  # coding=utf-8      def myList(num):      # 定义生成器      now = 0           # 当前迭代值,初始为0      while now < num:          val = (yield now)                      # 返回当前迭代值,并接受可能的send发送值;yield在下面会解释          now = now + 1 if val is None else val  # val为None,迭代值自增1,否则重新设定当前迭代值为val    my_list = myList(5)   # 得到一个生成器对象    print my_list.next()  # 返回当前迭代值  print my_list.next()    my_list.send(3)       # 重新设定当前的迭代值  print my_list.next()    print dir(my_list)    # 返回该对象所拥有的方法名,可以看到__iter__与next在其中  

 

运行结果:

 

 

具有yield关键字的函数都是生成器

,yield可以理解为return,返回后面的值给调用者。不同的是return返回后,函数会释放,而生成器则不会。在直接调用next方法或用for语句进行下一次迭代时,生成器会从yield下一句开始执行,直至遇到下一个yield。

 

#生成器函数,函数里只要有yield关键字def gen_func():

    yield 1

    yield 2

    yield 3

 

 

def fib(index):

    if index <= 2:

        return 1

    else:

        return fib(index-1) + fib(index-2)

 

 

def fib2(index):

    re_list = []

    n,a,b = 0,0,1

    while n<index:

        re_list.append(b)

        a,b = b, a+b

        n += 1

    return re_list

 

 

def gen_fib(index):

    n,a,b = 0,0,1

    while n<index:

        yield b

        a,b = b, a+b

        n += 1

 

 

for data in gen_fib(10):

    print (data)

# print (gen_fib(10))

# 斐波拉契 0 1 1 2 3 5 8

#惰性求值, 延迟求值提供了可能

 

 

def func():

    return 1

 

 

if __name__ == "__main__":

    #生成器对象, python编译字节码的时候就产生了,

    gen = gen_func()

    for value in gen:

        print (value)

    # re = func()

    # pass

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/540474.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python程序查找表示O(1)复杂度的数字所需的位数

Problem statement 问题陈述 Find total Number of bits required to represent a number in binary 查找以二进制表示数字所需的总位数 Example 1: 范例1&#xff1a; input : 10output: 4Example 2: 范例2&#xff1a; input : 32output : 6Formula used: 使用的公式&am…

正则split

string content "第1行导入失败&#xff0c;失败原因为&#xff1a; 《加班原因》字段必填";string[] resultString Regex.Split(content, "失败原因为&#xff1a;", RegexOptions.IgnoreCase);foreach (string i in resultString){Console.WriteLine(i…

将八进制数制转换为二进制,十进制和十六进制数制

1)将八进制数制转换为二进制数制 (1) Conversion of Octal Number System to Binary Number System) To convert octal numbers into binary numbers, we can use the relationship between octal and binary numbers. 要将八进制数转换为二进制数&#xff0c;我们可以使用八进…

[转载] Python的生成器

参考链接&#xff1a; Python中的生成器Generator Python的生成器 什么是生成器 创建python迭代器的过程虽然强大&#xff0c;但是很多时候使用不方便。生成器是一个简单的方式来完成迭代。简单来说&#xff0c;Python的生成器是一个返回可以迭代对象的函数。 怎样创建生…

想提高用户访问的响应速度和成功率还不赶快学习CDN

2019独角兽企业重金招聘Python工程师标准>>> 课程介绍 CDN可以将源站内容分发至最接近用户的节点&#xff0c;使用户可就近取得所需内容&#xff0c;提高用户访问的响应速度和成功率。解决因分布、带宽、服务器性能带来的访问延迟问题&#xff0c;适用于站点加速、点…

[转载] python迭代器、生成器和装饰器

参考链接&#xff1a; 有效地在Python中使用迭代 文章目录 生成器生成器表达式(generator expression)通过使用yield关键字定义生成器并行前戏高潮 迭代器迭代器概述iter()函数 创建迭代器创建一个迭代器(类)内置迭代器工具count无限迭代器cycle 无限迭代器&#xff0c;从一个…

java中的starts_Java Math类静态double nextAfter(double starts,double direction)示例

java中的starts数学类静态double nextAfter(双向启动&#xff0c;双向) (Math Class static double nextAfter(double starts , double directions) ) This method is available in java.lang package. 此方法在java.lang包中可用。 This method is used to return the double …

Python 核心编程(第二版)——条件和循环

Python 中的 if 子句由三部分组成: 关键字本身&#xff0c;用于判断结果真假的条件表达式&#xff0c; 以及当表达式为真或者非零时执行的代码块。if 语句的语法如下: if expression: expr_true_suite 单个 if 语句可以通过使用布尔操作符 and , or 和 not实现多重判断条件或…

[转载] 【python魔术方法】迭代器(__iter__和__next__)

参考链接&#xff1a; Python __iter __()和__next __()| 将对象转换为迭代器 文章目录 __iter__ 和 __next__真正的迭代器总结 python里面有很多的以__开始和结尾的函数&#xff0c;利用它们可以完成很多复杂的逻辑代码&#xff0c;而且提高了代码的简洁性&#xff0c;本文主…

Silverlight 异步单元测试

Silverlight 中的很多操作都是异步的&#xff0c;很多情况下要求单元测试也是异步的&#xff0c;但是介绍异步单元测试的文档很少。通过对 Silverlight Toolkit 中的 Microsoft.Silverlight.Testing 和 Microsoft.VisualStudio.QualityTools.UnitTesting.Silverlight 这两个文件…

网络拓扑 令牌环网 以太网_以太网连接中网络拓扑的类型及其框架 以太网技术...

网络拓扑 令牌环网 以太网A topology explains how physically the network is designed or what is the structure of the network. These designs are both physical and logical. There are many network topologies 4 like Bus, Star, Ring, and Mesh. But only two types …

Wafer晶圆封装工艺介绍

芯片封装的目的&#xff08;The purpose of chip packaging&#xff09;: 芯片上的IC管芯被切割以进行管芯间连接&#xff0c;通过引线键合连接外部引脚&#xff0c;然后进行成型&#xff0c;以保护电子封装器件免受环境污染&#xff08;水分、温度、污染物等&#xff09;&…

[转载] Python中的解析式和生成器表达式

参考链接&#xff1a; Python | 生成器表达式 解析式和生成器表达式 列表解析List Comprehension 语法 [返回值 for 元素 in 可迭代对象 if 条件]使用中括号[],内部是for循环&#xff0c;if条件语句可选&#xff0c;会返回一个新的列表 列表解析试优点 编译器会优化&…

java 数字字母进位_使用带有进位的8085微处理器将两个8位数字相乘

java 数字字母进位Problem statement: 问题陈述&#xff1a; Multiplication of two 8 bits numbers using 8085 microprocessor with carry. 使用带有进位的8085微处理器将两个8位数字相乘。 Algorithm: 算法&#xff1a; Load HL pair with initial data using LHLD comma…

[转载] Python3.0中普通方法、类方法和静态方法的比较

参考链接&#xff1a; Python中的类方法与静态方法 一、语法区别 刚接触Python中的面向对象&#xff0c;对于类方法和静态方法难以区分&#xff0c;通过查找知乎、CSDN论坛&#xff0c;废了好大的劲思路才逐渐明朗&#xff0c;所以就总结顺便分享一下。 首先开始编辑代码 # 普…

iOS:个人浅谈工厂模式

一、什么是工厂方法&#xff1f; 正式的解释是&#xff1a;在基类中定义创建对象的一个接口&#xff0c;让子类决定实例化哪个类。工厂方法让一个类的实例化延迟到子类中进行。工厂方法要解决的问题是对象的创建时机&#xff0c;它提供了一种扩展的策略&#xff0c;很好地符合了…

scanf 输入十六进制_使用C语言中的scanf()在字符变量中输入十进制,八进制和十六进制值...

scanf 输入十六进制Here, we will declare an unsigned char variable and input different formats value like decimal format, octal format and hexadecimal format. 在这里&#xff0c;我们将声明一个无符号的char变量&#xff0c;并输入不同格式的值&#xff0c;例如十进…

[转载] Python中pass的作用

参考链接&#xff1a; 如何在Python中编写空函数&#xff1f;请使用 pass语句 空语句 do nothing保证格式完整保证语义完整 以if语句为例&#xff0c;在c或c/java中&#xff1a; if(true) ; //do nothing else { //do something } 对应于python就要这样写&#xff…

wrf 嵌套网格作用_在网格系统中使用响应列,嵌套列和偏移列 引导程序

wrf 嵌套网格作用介绍 (Introduction) In the previous article, we have learnt what is grid and grid system and how it works? Now, we will learn about how Responsive column, Nesting Columns and Offset Columns works and how to use them? If you have any doubt…

[看书笔记]《深入java虚拟机》——java体系结构(二)

java虚拟机的三种含义&#xff1a; - 抽象的规范 - 一个具体的实现 - 一个运行中的虚拟机实例 ---------------------java虚拟机的生命周期&#xff1a; java虚拟机实例的天职就是负责运行一个java程序。 启动一个java程序&#xff0c;一个虚拟机实例诞生了&#xff1b;程序关闭…