迭代器

自始至终,都有一个概念一直在用,但是我们却没来都没有人在的深入剖析它。这个概念就是迭代。

迭代的意思有点类似循环,每一次的重复的过程被称为迭代的过程,而每一次迭代得到的结果会被用来作为下一次迭代的初始值。提供迭代方法的容器称为迭代器,通常接触的迭代器有序列(列表、元组、字符串)还有字典也是迭代器,都支持迭代的操作。举个列子,通常使用for循环进行迭代。

>>> for i in "python":print(i)打印结果
p
y
t
h
o
n

字符串就是一个容器,同时也是一个迭代器,for语句的作用就是触发这个迭代器的迭代功能,每次从容器里面依次拿出一个数据就,这就是迭代操作。

字典和文件也是支持迭代操作的:

>>> list1 = {"python":"python3.x",\"go":"go是一种语言语法",\"int":"python关键字",\}
>>> for i in list1:print("%s --> %s"%(i,list1[j]))>>> for i in list1:print("%s --> %s"%(i,list1[i]))

打印结果;

python --> python3.x
go --> go是一种语言语法
int --> python关键字

关于迭代,python还提供了两个BIF:iter()  next()

对一个容器对象调用iter()就得到它的迭代器,调用next()迭代器就会返回下一个值,然后怎么结束了?如果迭代器没有值可以返回,python将抛出一个叫做Stoplteration的异常。

>>> string = "python"
>>> it = iter(string)
>>> next(it)
'p'
>>> next(it)
'y'
>>> next(it)
't'
>>> next(it)
'h'
>>> next(it)
'o'
>>> next(it)
'n'
>>> next(it)
Traceback (most recent call last):File "<pyshell#26>", line 1, in <module>next(it)
StopIteration

所以,利用这两个BIF,可以分析出for语句其实就是这么工作的:

>>> string = "python"
>>> it = iter(string)
>>> while True:try:each = next(it)except StopIteration:breakprint(each)p
y
t
h
o
n

那么实现迭代器的魔法方法就有两个:__iter__()   __next__()

一个容器如果是迭代器,就必须实现__iter__()方法,这个方法实际上就是返回迭代器本身。接下来就是重点实现的是__next__()魔法方法,因为他决定了迭代器的规则,看一段例子:

>>> class Fibs():def __init__(self):self.a = 0self.b = 1def __iter__(self):return selfdef __next__(self):self.a,self.b = self.b,self.a+self.breturn self.a>>> fibs = Fibs()
>>> for i in fibs:if i < 20:print(i)else:break1
1
2
3
5
8
13

这个迭代器的唯一亮点就是没有终点,所以如果没有跳出循环,它会不断迭代下去。那么就可以加一个参数,用于控制迭代的范围。

>>> class Fibs():def __init__(self,n = 20):self.a = 0self.b = 1self.n = ndef __iter__(self):return selfdef __next__(self):self.a,self.b = self.b,self.a+self.bif self.a > self.n:raise StopIterationreturn self.a>>> fibs = Fibs()
>>> for i in fibs:print(i)1
1
2
3
5
8
13

生成器

前面是迭代器,下面来说生成器

生成器其实就是迭代器的一种实现,那既然迭代器就可以实现,为何还要生成器了?生成器之所以存在就是为了是python更为简洁,因为迭代器需要我们自己去定义一个类和实现相关的方法,而生成器则需要在普通函数中加一个yield语句即可。

生成器的发明,使python模仿协同程序的概念得以实现,所谓协同程序,就是可以运行的独立函数调用,函数可以暂停或者挂起,并需要的时候从程序离开的地方继续或重新开始。

对于调用一个普通的python函数,一般是从函数的第一行代码开始执行,结束与return语句,异常或函数所有语句执行完毕,一但函数将控制权交给调用者,就意味着全部结束。函数中做的所有工作以及保存在局部变量中的数据将丢失。再次调用这个函数时一切都将从头创建。

python是通过生成器来实现类似于协同程序的概念:生成器可以暂时挂起函数,并保留函数的局部变量等数据,然后在再次调用他的时候,从上次暂停的位置继续执行下去。

举个例子:

>>> def myGen():print("生成器被执行!")yield 1yield 2>>> myG = myGen()
>>> next(myG)
生成器被执行!
1
>>> next(myG)
2
>>> next(myG)
Traceback (most recent call last):File "<pyshell#76>", line 1, in <module>next(myG)
StopIteration

通过例子,当函数结束的时候,一个StopIteration异常就会被抛出。由于Python的for循环会自动调用next()方法和处理StopIteration异常,所以for循环当然也是可以对生成器产生作用的:

>>> def myGen():print("生成器被执行!")yield 1yield 2>>> myG = myGen()
>>> for i in myG:print(i)生成器被执行!
1
2

前面说的斐波那契数列例子,也可以用生成器实现:

>>> def fibs():a,b = 0,1while True:a,b = b,a+byield a>>> for i in fibs():if i>100:breakprint(i)1
1
2
3
5
8
13
21
34
55
89

写到现在,可以很好的用类别推导式了,哈哈,先来看下下面的什么意思吧

>>> a =  [i for i in range(100) if not (i%2) and i%3]
>>> print(a)
[2, 4, 8, 10, 14, 16, 20, 22, 26, 28, 32, 34, 38, 40, 44, 46, 50, 52, 56, 58, 62, 64, 68, 70, 74, 76, 80, 82, 86, 88, 92, 94, 98]

含义很简单的,打印100以内能被2整除,不能被3整除

>>> b = {i:i%2==0 for i in range(10)}
>>> b
{0: True, 1: False, 2: True, 3: False, 4: True, 5: False, 6: True, 7: False, 8: True, 9: False}

还有集合推导式:

>>> c = {i for i in [1,1,2,3,3,4,5,5,5,6,7,7,7,8]}
>>> c
{1, 2, 3, 4, 5, 6, 7, 8}

那么有没有字符串推导式,来验证下

>>> d = "I love python!"
>>> d
'I love python!'

看吧,不对吧,打印的是整个包含在字符串中的,所以不存在字符串推导式的说法,那元组了?

>>> e = (i for i in range(10))
>>> e
<generator object <genexpr> at 0x0000000003031360>

看打印出来的信息是generator,这就是生成器,用小括号括起来的正是生成器,来看下效果

>>> next(e)
0
>>> next(e)
1
>>> next(e)
2
>>> next(e)
3
>>> next(e)
4
>>> next(e)
5>>> next(e)6>>> next(e)7

用for循环吧剩下的打印出来

>>> for i in e:print(i)8
9

生成器推导式如果作为函数的参数,可以直接写推导式,而不用加小括号(这个很牛气吧)。

>>> sum(i for i in range(100) if i%2)
2500

转载于:https://www.cnblogs.com/pinpin/p/9926366.html

python_魔法方法(六):迭代器和生成器相关推荐

  1. [Python]小甲鱼Python视频第048课(魔法方法:迭代器) )课后题及参考解答

    # -*- coding: utf-8 -*- """ Created on Sun Mar 24 20:24:02 2019@author: fengs "& ...

  2. python_魔法方法(二):算术运算

    python2.2之后,对类和类型做了同意,将int().float().str().list().touple()这些BIF转换为工厂函数 >>> type(len) <cl ...

  3. python入门——P48魔法方法:迭代器

    迭代 上一次的输出,作为下一次的输入,返回自身,代码如下 dic = {"00":"a", "01":"b", &quo ...

  4. python全栈开发-Day11 迭代器、生成器、面向过程编程

    一. 迭代器 一 .迭代的概念 迭代器即迭代的工具,那什么是迭代呢? 迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值 while True: #只是单纯地重复,因而 ...

  5. python魔法函数和装饰器_python魔法方法、构造函数、序列与映射、迭代器、生成器...

    在Python中,所有以__双下划线包起来的方法,都统称为"魔术方法".比如我们接触最多的__init__,魔法方法也就是具有特殊功能的方法. 构造函数 构造函数不同于普通方法,将 ...

  6. 第九章 魔法方法、特性和迭代器

    第九章 魔法方法.特性和迭代器 构造函数 构造函数(constructor),它其实就是初始化方法,只是命名为__init__. 构造函数不同于普通方法的地方在于,将在对象创建后自动调用它们. 在Py ...

  7. Python基础教程-第9章-魔法方法、特性和迭代器

    在Python中,有些名称很特别,开头和结尾都是两个下划线.你在本书前面已经见过一些, 如__future__. 在这样的名称中,很大一部分都是魔法(特殊)方法的名称.如果你的对象实现了这些方法,它们 ...

  8. Python_基础_(迭代器,生成器)

    一,迭代器 1,迭代器协议:对象必须具有一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopInteration异常,以来终止迭代(只能往后走,不能向前进) 2,可迭代对象:实现 ...

  9. python迭代器两个基本方法可供参考_浅析python迭代器和生成器

    可迭代对象 概念 一个对象(在Python里面一切都是对象)只要实现了只要实现了__iter__()方法,那么这个对象就是可迭代对象 常见的可迭代对象 集合或序列类型(如list.tuple.set. ...

最新文章

  1. 如何才能信任你的深度学习代码?
  2. Loadrunner在post请求的cookie中插入其它多个值
  3. Fiddler 自定义规则编写
  4. struts2教程(5)--请求参数校验
  5. NASM在Ubuntu上的安装与简单使用
  6. mmsPlayer 2.0 将开源java部分
  7. 从 DevOps 到 Serverless
  8. Minimal Square CodeForces - 1360A(简单思维和图形判断)
  9. Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration.
  10. Java并发编程实战————售票问题
  11. Java多线程学习(二)synchronized关键字(1)
  12. 双十一快到了,快递却不干了?
  13. 万字综述,GNN在NLP中的应用,建议收藏慢慢看
  14. websocket.onmessage回调没反应_等待A股暴跌回调补四缺口倒计时第二十四天——8月19日总结...
  15. Oracle数据库之导入导出
  16. mime 类型列表_MIME类型的完整列表
  17. 77GHz雷达信号处理流程框图及应用方案
  18. 鲁豫有约--之分享李连杰的私密生活
  19. Unity笔记-29-ARPG游戏项目-01-第三人称相机
  20. ArcGIS earth 1.0 beta体验报告——给我一个按钮我将转动整个地球

热门文章

  1. SlideringDrawer的使用(抽屉效果)
  2. 26.python常用端口号
  3. (三十三)设计模式之混合模式
  4. LeetCode 695 Max Area of Island
  5. vmware智能资源调整
  6. 三种流行防火墙配置方案分析与对比
  7. 集群节点间的延迟问题
  8. AssetManager (资源路径+当前手机配置信息)
  9. 【浏览器】缩放是缩放CSS像素(缩放比例为1时,一个CSS像素等于一个屏幕像素)
  10. Dalvik分析(一)