迭代器生成器异步协程并行

本文介绍了Python中的迭代器和生成器概念,重点讲解了如何通过它们实现内存高效利用,包括列表推导与生成器的区别,以及如何创建和使用生成器函数。实例涵盖了斐波那契数列和月饼制作过程,展示了生成器在实际编程中的应用场景。
摘要由CSDN通过智能技术生成
import time
from collections import Iterator
from collections import Iterable

列表、字符串、字典、元组、集合等凡是可以直接作用于for循环的对象统称为可迭代对象:Iterable
而可以用next的方法调用并不断返回下一个值的对象称为迭代器:Iterator
可以使用iter()函数把listdictstr等Iterable变成Iterator:
print(isinstance({},Iterable))
print(isinstance('abc',Iterable))
print(isinstance({},Iterator))
print(isinstance('abc',Iterator))
print(isinstance(iter({}),Iterator))
print(isinstance(iter('abc'),Iterator))
#输出:
'''
True
True
False
False
True
True
'''


1、迭代  当创建一个列表对象后,可以一个接一个读取列表中的值,这个过程就叫做迭代。
new_list = [1,1,2,2]
for i in new_list:
    #print(i, end = ' ')
    # 输出:
    '''
   1 1 2 2 
    '''
    #print(i)
#输出:
'''
1
1
2
2

'''
#列表推导表达式
mylist作为可迭代对象,在使用前先存储所有值,规模越大,
存储时间就越长,所占内存就越大,如下
'''
mylist = [2*x+1 for x in range(1000000)]
for i in mylist:
    print(i, end=' ')
'''
2、生成器(Generator)  也是可迭代对象,生成器就是一个迭代器。
生成器用来解决的内存资源消耗的问题。即取即用,不占内存。依次取用,不可跳取。
create_g=(2*x+1 for x in range(10))
print(create_g) #<generator object <genexpr> at 0x00AE4220>
使用一对方括号创建的是列表对象,而使用一对圆括号创建的就是迭代器对象,
如果直接输出,会输出迭代器对象的地址,只有通过for...in...语句或调用
迭代器的相应方法才能输出迭代器对象中的值。而且第二次对迭代器对象进行迭代,
什么都不会输出,这是因为迭代器只能被迭代一次,
而且被迭代的值使用完,是不会再保存在内存中的。
'''
for i in create_g:
    print(i, end=' ')
print('\n'+"第二次迭代分割线")
for i in create_g:
    print(i, end=' ')
'''
#通过next()函数(or __next__())获得generator的下一个返回值:
'''
print(create_g.__next__())
print(create_g.__next__())
print(next(create_g))
'''
#输出:
'''
1
3
5

'''
generator保存的是算法,每次调用next(g),就计算出g的下一个元素的值,
直到计算到最后一个元素,没有元素可取时,抛出StopIteration的错误

yield  生成器对象是通过使用yield关键字定义的函数对象,因此,生成器也是一个函数。
通过yield语句创建生成器函数。如创建斐波那契数列:
def fib(max):
    n,a,b=0,0,1
    while n<max:
        a,b=b,a+b
        n+=1
        m0=yield a 
        #先执行yield a,再将值传给m0,此处的m0只能通过send函数传值
        print('yield a % s' % a)
        print('yield m0 % s' % m0)
        m1=yield 'try'
        print('yield try m1 % s' % m1)
    return "Finished!"
函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,
在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。
'''
t1 = fib(3)
x = next(t1)
print('next x %s' % x)
y = t1.send(10)
print('next y %s' %y)
z = next(t1)
print('next z %s' % z)
'''
#输出:
'''
next x 1
yield a 1
yield m0 10
next y try
yield try m1 None
next z 1
yield a 1
yield m0 None
'''
运行过程说明:
第一步:r = fib(3),实例化一个生成器对象
第二步:调用next() ,遇到yield 暂停,返回值1,赋值给x
第三步:打印x,>>next x 1
第四步:传值10,在暂停处接受值10,把10传给m0,继续运行,打印a的值,遇到第二个yield,
将字符串try赋值给y
第五步:打印y,>>next y try
第六步:调用next() ,接着之前yield 'try'继续执行,没有值传给m1,
后面也没有yield的语句,打印m1为None,
此时,n,a,b分别为111,继续执行while,经过第二次公式,n,a,b为212,将a值即1传给z。

#生成器并行
food = ["莲蓉馅", "紫薯馅", "豆沙馅", "蛋黄馅"]
def consumer(name):
    print("%s准备吃月饼了!" % name)
    while True:
        yuebing = yield 'n' 
此处的=号只能通过send函数来传值,而不是将yield语句后的字符串n值传给yuebing
        print("[%s]月饼来了,被[%s]吃了!" % (yuebing, name))
def producer(name):
    c1 = consumer('哥哥')
    c2 = consumer('姐姐')
    c1.__next__()
    c2.__next__()
    print("%s开始准备做月饼啦" % name)
    for i in range(6):
        print("第%d次做了%s个月饼" % (i + 1, len(food)))
        stt=time.time()
        time.sleep(i+2)  #做月饼所花时间
        endt=time.time()
        print("花了%s时间"%(endt-stt))
        f1 = food[i]
        c1.send(f1)
_next__()next()或send()函数都是在上次执行的地方继续执行,
直到执行到yield语句,或者该生成器函数执行完
        food.append(f1)
        c2.send(food[i])
f1的值没变,所以哥哥姐姐吃的是同一种馅的月饼
        
producer('妈妈')

报错:DeprecationWarning: Using or importing the ABCs from ‘collections’ instead of from ‘collections.abc’ is deprecated since Python 3.3, and in 3.9 it will stop working
from collections import Iterator
翻译:Deprectionwarning: 使用或导入‘ collections’而不是‘ collections.abc’中的 abcs,自 python 3.3以来就不推荐使用,在3.9中,它将停止使用 collections import iterator

即将语句:

from collections import Iterator
from collections import Iterable

改为:

from collections.abc import Iterator
from collections.abc import Iterable

就不会报错了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值