美文网首页
python生成器和迭代器

python生成器和迭代器

作者: Cache_wood | 来源:发表于2021-12-01 09:34 被阅读0次

@[toc]

观察者模式

亦称
– 发布(publish )-订阅(Subscribe)模式
– 模型-视图(View)模式
– 源-收听者(Listener)模式
– 从属者模式

要义
– 一个目标对象管理所有依赖于它的观察者对象,并且在它本身的状态改变时主动发出通知
– 观察者模式完美地将观察者和被观察的对象分离

  • 优点
    – 观察者与被观察者之间抽象耦合
    – 可以触发多个符合单一职责的模块
    – 可以很方便地实现广播
  • 场景
    – 消息交换,如消息队列;
    – 多级触发,如一个中断即会引发一连串反应
  • 缺点
    – 效率不一定高
import time
class Investor:
    def __init__(self,name,stock):
        self._name=name
        self._stock=stock

    @property
    def stock(self):
        return self._stock
    @stock.setter
    def stock(self,value):
        self._stock=value

    def update(self):
        print("{} invest on {} with price {}: sell it now!!!".format(self._name,self._stock.name,self._stock.price))

class Stock:
    def __init__(self,name,price):
        self._name=name
        self._price=price
        self._investors=[]

    @property
    def name(self):
        return self._name
    
    @property
    def price(self):
        return self._price

    @price.setter
    def price(self,value):
        if self._price>value:
            self.notify()
        self._price=value
    
    def attach(self,investor):
        self._investors.append(investor)

    def notify(self):
        for investor in self._investors:
            investor.update()

def main():
    s=Stock('区块链',11.11)
    i1=Investor('zjc',s)
    i2=Investor('lys',s)
    s.attach(i1)
    s.attach(i2)
    s.price=13
    time.sleep(1)
    s.price=10

if __name__=='__main__':main()  

zjc invest on 区块链 with price 13: sell it now!!!
lys invest on 区块链 with price 13: sell it now!!!

迭代

  • 通过 for … in 等遍历数据结构如tuple,list,dict字符串等
  • 判断一个对象是否可迭代
from collections import Iterable
isinstance([1,2,3],Iterable)
  • 同时迭代序号和元素
for i,value in enumerate(['A','B','C']):
    pass

生成器

  • 通过列表推导式构建生成器
L = [x*x for x in range(10)] #列表
G = (x*x for x in range(10)) #生成器
  • 通过next()函数获得generator的下一个返回值

  • 通过for … in 进行遍历

  • 通过定义函数构建生成器

    • 函数定义需要包含yield关键字
    • 在执行中遇到yield会中断,下次继续执行
      暂停并保存当前所有运行信息,返回yield的值,并在下一次执行next()方法时从当前位置继续运行
  • 获取返回值需要捕获StopIteration异常

  • 注意区分普通函数和generator函数

  • 普通函数调用直接返回结果

  • generator函数的调用实际返回一个generator对象

def fib(max):
    n,a,b=0,0,1
    while(n<max):
        yield b
        a,b=b,a+b
        n+=1
    return 'done'

print(fib(6))

<generator object fib at 0x000001E77234AB30>
#生成器不会直接直接打印出值,只会一个个加载

for f in fib(6):
    print(f)
1
1
2
3
5
8
#循环打印出值,但是不会出'done'

f=fib(6)
while True:
    try:
        print(next(f))
    except StopIteration as si:
        print(si.value)
        break
1
2
3
5
8
done  #这种方法可以打印出'done'
from collections import Iterable
#flatten函数用来展平
def flatten(items,ingore_types=(str,bytes)):
    for x in items:
        if isinstance(x,Iterable) and not isinstance(x,ingore_types):
            yield from flatten(x,ingore_types)
        else:
            yield x

items=[1,2,[3,4,5],[6,7],[[[8]]],9,10]
finput=list(flatten(items))  #转化为列表
print(finput)
#for x in flatten(items):
#   print(x)

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

迭代器

  • 可以被next()函数调用并不断返回下一个值的对象称为迭代器
  • 迭代器可以记住遍历位置
  • 迭代器只能往前不能后退(“消耗”数据)
  • 可以使用isinstance()判断一个对象是否是Iterator对象
isinstance((x for x in range(10)),Iterator)
  • 生成器都是迭代器,但是list,dict,str虽然是Iterable,却不是Iterator
  • list,dict,strIterable变成Iterator可以使用iter()函数
  • Iterator对象表示一个数据流
    next()函数调用并不断返回下一个数据在,直到没有数据抛出StopIteration错误
    可将该数据流看作是长度未知的有序序列,只能不断通过next()函数实现按需计算下一个数据
    可表示无限大数据流,例如全体自然数,而使用list等不可能存储全体自然数
创建迭代器
  • iter()函数
  • 把一个类作为一个迭代器使用需要在类中实现两个方法__iter__()__next__()
  • __iter__()返回一个特殊的迭代器对象,这个对象实现了__next__()方法
  • __next__()方法返回下一个元素并通过StopIteration异常标识迭代的完成
from typing import Iterator

class Numbers:
    def __init__(self,start=1,step=1,max=100):
        self._start=start
        self._step=step
        self._max=max
        self._a=self._start
        #self._list=[]

    def __iter__(self):
        
        return self
        #return iter(self._list)

    def __next__(self):
        if self._a <= self._max:
            x = self._a
            self._a += self._step
            return x
        else:
            raise StopIteration('大于max:{}'.format(self._max))

num=Numbers(start=2,step=2,max=100)
myiter=iter(num)

for i in range(10):
    print(next(myiter))

2
4 
6 
8 
10
12
14
16
18
20
迭代器相关工具

相关文章

网友评论

      本文标题:python生成器和迭代器

      本文链接:https://www.haomeiwen.com/subject/cgldxrtx.html