博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python Day04
阅读量:5023 次
发布时间:2019-06-12

本文共 2746 字,大约阅读时间需要 9 分钟。

一、迭代器与生成器:

迭代器(iterator):

迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退,迭代器的一大优点是不要求事先准备好事代过程中所有元素。迭代器仅仅在迭代至某个元素时才计算该元素,元素在被迭代器所迭代之前,元素可以不存在,或被销毁。这个特点使得迭代器特别适合用于遍历一些巨大的或是无限的集合,比如几个 G 的文件。

特点:

  1、访问者不需要关心迭代器的内部结构,仅需通过迭代器的 next() 方法不断去取下一个内容。

  2、不能随机访问集合中的某个值,只能从头至尾依次访问。

  3、集合中有元素 [a,b,c,d] 迭代至元素 c 时,不能在向后访问元素 b  (PS:迭代器不能后退)

  4、可以容易的循环较大数据集合,节省内存。

  5、__iter__ 方法:如果某个类可被迭代,类中必须要有这个方法。

  6、迭代器在取值的时候,不会将集合中的值一次全部取出,迭代一次,取出一个值,一直取到迭代器中无值,也就意味着在至值 n 之前,并不需要 n 有值。

生成迭代器:

>>>a = iter([1,2,3,4])   # iter 方法将指定的集合变成迭代器>>>print (a)                  # 迭代器中的值只能被迭代取出。
# 返回的是迭代器的内存地址。>>> a.__next__() # 迭代器有 next 方法,用来迭代集合中的下一个值1>>> a.__next__()2>>> a.__next__()3>>> a.__next__()4>>> a.__next__()5>>> a.__next__() # 迭代器中只有五个值,迭代到第六次时,就会超出值个数,导致停止迭代Traceback (most recent call last): File "F:/Blogs.py", line 14, in
StopIteration # 停止迭代。

生成器(generator):

通过 list 方法,可以创建一个列表,但是内存容量是有限的,假如创建一个包含1000万元素的列表,加载至内存需要花费较长时间,但是我们仅仅需要它的前几个元素,整个列表也需要被加载至内存,此时内存空间就被浪费了。

定义:一个函数被调用时返回一个迭代器,那这个函数就叫生成器(generator),如果函数中包含 yield 语法,那这个函数就会变成生成器。

代码:

def cash(max):    while max >0:        max -= 1        yield 1    # 每次执行至 yield 时,就会使函数中断,并保存中断位置        print ("我来取钱了")   # 当第 yield 中断后,返回时 就会打印此句ATM = cash(5)      # 将生成器 cash 的内存地址,赋值给 ATM 变量,执行 ATM 就等于执行生成器 cashprint ("取到 %s 万" %ATM.__next__())   # 生成器的 __next__ 方法print ("取到 %s 万" %ATM.__next__())print ("取到 %s 万" %ATM.__next__())print ("取到 %s 万" %ATM.__next__())print ("取到 %s 万" %ATM.__next__())print ("取到 %s 万" %ATM.__next__())   # 生成器中只有5个元素此时再取就会报错> 取到 1 万      # yield 中断后,__next__() 方法输出具体数值> 我来取钱了    # 第一次 __next__ 方法执行完毕,返回函数继续 yield 下面执行打印此句> 取到 1 万> 我来取钱了> 取到 1 万> 我来取钱了> 取到 1 万> 我来取钱了> 取到 1 万> 我来取钱了> Traceback (most recent call last):>      print ("取到 %s 万" %ATM.__next__())> StopIteration

作用:

yield 主要效果就是可以使函数中断,并保存中断状态,记录中断在了哪个位置,当下一次调用这个函数时,继续上次 yield 中断的位置继续向下执行。

另外,还可通过 yield 实现在单线程的情况下实现并发运算效果。

import time    # 导入时间模块def consumer(name):    # 生成器    print ("%s 准备吃包子啦!" %name)    while True:        baozi = yield    # 断点,yield 接收 send 方法传递进来的参数        print ("包子[%s]来了,被[%s]吃了!" %(baozi,name))  #def producer(name):    c = consumer('A')    # 传递给生成器的变量    c2 = consumer('B')  # 传递给生成器的变量    c.__next__()           # 触发取生成器中的内容    c2.__next__()         # 触发取生成器中的内容    print ("老子开始准备做包子啦!")    for i in range(3):    # 循环十次,退出程序        time.sleep(1)       # 暂停一秒        print("做了2个包子!")        c.send(i)               # 通过变量向 yield 传递参数,发送后即进入迭代器        c2.send(i)             # 同上producer("alex")           # 触发函数> A 准备吃包子啦!> B 准备吃包子啦!> 老子开始准备做包子啦!> 做了2个包子!> 包子[0]来了,被[A]吃了!> 包子[0]来了,被[B]吃了!> 做了2个包子!> 包子[1]来了,被[A]吃了!> 包子[1]来了,被[B]吃了!> 做了2个包子!> 包子[2]来了,被[A]吃了!> 包子[2]来了,被[B]吃了!

 

转载于:https://www.cnblogs.com/jayy/p/5154818.html

你可能感兴趣的文章
python list和tuple
查看>>
基础薄弱的反思
查看>>
ORACLE增删改查以及case when的基本用法
查看>>
[转]oracle10客户端PL/SQL Developer如何连接远程服务器上的oracle数据库
查看>>
HTML5 表单元素和属性
查看>>
SDUTOJ 2498 数据结构实验之图论十一:AOE网上的关键路径
查看>>
使用SpringSocial开发QQ登录
查看>>
好玩的游戏
查看>>
2.6. Statistical Models, Supervised Learning and Function Approximation
查看>>
代码说明call和apply方法的区别 (咱们这方面讲解的少,这样的题有变式,需要举例讲解一下)...
查看>>
T-SQL 类型转换
查看>>
在eclipse中设计BPMN 2.0工作流定义的根本步骤
查看>>
Json对象与Json字符串互转(4种转换方式)
查看>>
PAT甲级1002 链表实现方法
查看>>
查看Linux信息
查看>>
Python中sys模块sys.argv取值并判断
查看>>
【详记MySql问题大全集】四、设置MySql大小写敏感(踩坑血泪史)
查看>>
并查集
查看>>
ubuntu 11.04下android开发环境的搭建!
查看>>
Bzoj 3343: 教主的魔法
查看>>