博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python 迭代器与生成器
阅读量:4972 次
发布时间:2019-06-12

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

一 迭代器

  可迭代对象:Iterable,例如,ist,str,tuple,dict,set,range(100)。

    具有__iter__方法的叫做可迭代对象。

  迭代器:Iterator,例如,文件句柄。

    具有__next__,__iter__方法的叫做迭代器。

    迭代器调用__iter__()方法还是自身。  

  可迭代对象与迭代器的关系:

    可迭代对象调用了__iter__()方法变成迭代器。

  2 判断是否是可迭代对象,迭代器的方法。

    1 可迭代对象有__iter__方法,没有__next__方法

     迭代器有__iter__ __next__方法

    2 from collections import Iterable/Iteration  

       isinstance()方法

  3 for循环的本质

    for循环可以遍历一个可迭代对象,也可以遍历一个迭代器。

    当遍历一个可迭代对象时,会自动调用其__iter__()方法,变为一个迭代器。然后调用__next__()方法。遇到StopIteration终止。

  4 迭代器取值与索引取值的对照

    迭代器的缺点:不能定点取值。

           不能往回取值。

    迭代器的优点:惰性计算,节省内存。

             可以遍历字典,集合取值。这点是索引无法做到的。无序且不知道有哪些key值。

 

 

二 生成器 Generator

  生成器本质上是迭代器。  

  生成器是用户写出来的。

  1 生成器的分类

    带有yield关键字的生成器函数

    由生成器表达式生成的生成器 

  2 生成器函数

    带有yield关键字的函数叫做生成器函数。

    与普通函数的不同之处:调用生成器函数返回来是生成器。

    yield关键字:  

      与return相同的部分:

      与rerurn不同的部分:

  

三 生成器的应用

  生成器可以模仿管道的概念,借助生成器,可以一直往外传值。

  也可以用send方法给生成器传值。

def foo():    money=0    day=0    average=0    while True:        value=yield average        money+=value        day+=1        average=money/dayg=foo()print(g.__next__())print(g.send(200))

  一些想法:

  想用生成器,首先是要定义函数,函数体内有yield关键字。

  生成器一般与循环配合的使用。

  生成器通过yield向外传值。也可以用send往内传值。

 

四    egon课上讲的例子。

  表达式形式的生成器到底有什么用。 拿到生成器,从外边给yield传值。  

  注意:返回来看,send方法调用的必是生成器,send括号内的内容给生成器,拿到生成器后面的返回值。send的作用,传值和__next__()

  进阶一,yiled没有返回值。

def init(func):    def wrapper(*args,**kwargs):        res=func(*args,**kwargs)        res.send(None)  #等价于next(res),等价于res.__next__()        return res    return wrapper@initdef eater(name):    print('{} ready to eat '.format(name))    while True:        food=yield        print('{} is eating {}'.format(name,food))e=eater('alex')e.send('dog shit')

  输出:

alex ready to eat alex is eating dog shit

 

  进阶二 yield加上返回值。

def init(func):    def wrapper(*args,**kwargs):        res=func(*args,**kwargs)        res.send(None)  #等价于next(res),等价于res.__next__()        return res    return wrapper@initdef eater(name):    print('{} ready to eat '.format(name))    food_list=[]    while True:        food=yield food_list        food_list.append(food)        print('{} is eating {}'.format(name,food))e=eater('alex')print(e.send('dog shit'))print(e.send('cat shit'))

  输出:

alex ready to eat alex is eating dog shit['dog shit']alex is eating cat shit['dog shit', 'cat shit']

  

  进阶三 进阶二中的狗屎,猫屎参数是写死了。可以专门写一个函数,专门make shit。

    分步骤一:

def make_shit(n):    for i in range(n):         屎是造出来了,但要传值,给人吃呀

    分步骤二:

def make_shit(people,n):    for i in range(n):        people.send('shit{}'.format(i))             加入一个参数,造完shit后,通过send传值people

    分步骤三:

def init(func):    def wrapper(*args,**kwargs):        res=func(*args,**kwargs)        res.send(None)  #等价于next(res),等价于res.__next__()        return res    return wrapper@initdef eater(name):    print('{} ready to eat '.format(name))    food_list=[]    while True:        food=yield food_list        food_list.append(food)        print('{} is eating {}'.format(name,food))def make_shit(people,n):    for i in range(n):        people.send('shit{}'.format(i))e = eater('alex')make_shit(e,5)

  输出:

alex ready to eat alex is eating shit0alex is eating shit1alex is eating shit2alex is eating shit3alex is eating shit4

  make_shit 函数造出shit后不断send给people。

  实际上两个函数协同工作的效果。一个函数不断造值,不断发送给另一个函数。 外面的函数给内部的生成器传值。

  进阶四:

  模拟grep 命令。

转载于:https://www.cnblogs.com/654321cc/p/7473171.html

你可能感兴趣的文章
openstack dpdk
查看>>
springmvc跳转方式
查看>>
Linux安装Redis
查看>>
IOS 第三方管理库管理 CocoaPods
查看>>
背景色渐变(兼容各浏览器)
查看>>
Redis中7种集合类型应用场景
查看>>
MariaDB 和 MySQL 比较
查看>>
MYSQL: 1292 - Truncated incorrect DOUBLE value: '184B3C0A-C411-47F7-BE45-CE7C0818F420'
查看>>
Java JPA @Transient 在Hibernate中应用
查看>>
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
查看>>
springMVC Controller 参数映射
查看>>
JDK1.8源码分析02之阅读源码顺序
查看>>
java使用jsp servlet来防止csrf 攻击的实现方法
查看>>
缓存穿透/击穿/雪崩/降级
查看>>
我的作品
查看>>
【bzoj题解】2186 莎拉公主的困惑
查看>>
Protocol Buffer学习笔记
查看>>
Update 语句
查看>>
HBuilder打包Android apk 支付不了问题解决
查看>>
poj2594——最小路径覆盖
查看>>