python迭代器和生成器

迭代器

迭代的定义

  • 迭代和递归的区别:递归是重复调用自身以达到循环的目的,而迭代是每一次调用的变量会成为下一次调用的初始值。
  • 迭代器协议:对象必须要提供一个next方法,执行方法要么返回迭代中的下一项,要么就引起一个Stopiteration异常,以终止迭代,python内部的for,sum等皆使用了迭代方法,只能前进不能后退,因此节省内存。
  • 迭代对象:实现了迭代器协议(拥有__next__方法)的对象(如何实现:对象内部会定义一个__iter__()方法来生成一个迭代对象)。
  • 可迭代对象是指可以返回一个迭代器的对象,拥有__iter__()方法,而迭代对象指的就是迭代器。

迭代器的基本使用方法

方法一:
l = [ 1,2,3] #列表具有iter方法,因此列表为一个可迭代对象
i = iter(l) #生成一个迭代器
printnext(i))
方法二:
l = "123" #字符串也也具有可迭代方法
i = l.__iter__()
print(i.__next__())

用迭代协议来理解for循环

l = [ 1,2,3]
for i in l: # i = l.__iter__()
	print(i) # print(i.__next__())	
  • for循环首先将一个将循环对象变成了一个可迭代对象
  • 之后自动捕捉了Stopiteration异常,停止了迭代

生成器

生成器的定义

生成器可以理解为一种生成迭代器的函数,简单理解生成器其实就是一个特殊迭代器。
生成器会调用yield函数,每次基于上一次的运行结果返回一个值。

生成器的使用

方法一:
def gen():
    yield 1
    yield 2
    yield 3

x = gen()
print(next(x)) #一次输出一个值
print(next(x))
printnext(x))
# 1
# 2
# 3

方法二:生成器表达式
a = ( i for i in range(3)) #和列表表达式类似,生成一个迭代器对象
print(next(a))
print(next(a))
print(a.send(None) #send函数在下一节生产者消费者模型中会详细解释
# 0
# 1
# 2

使用生成器的实例

def get_population():
    with open("test.txt","r") as f:
    #{"name":"北京","population":100} 每一行的内容
        for i in f:
            yield i

g = get_population()
all1 = sum(eval(j)["population"] for j in g)
#由于取出每一行都是字符串,因此需要使用eval函数来进行转换成字典
g1 = get_population()
for city in g1:
    print("%s占全国人口的%.2f%%"%(eval(city)["name"],eval(city)["population"]/all1*100))
    #%%可以打印出%

生产者消费者模型

send()函数

send函数的功能和next函数一样,是进行一次迭代的操作,但是和next不同的是,send函数必须传入一个参数,这个参数的值会赋给上一次迭代的yield变量。
yield有两个功能:1、给函数提供一个返回值并将函数的运行状态停留;2、作为参数接收变量

def my_gen():
    print("first line")
    first = yield 1 
    print("second line",first)
    yield 2

g = my_gen()
res = next(g)
print(res)
res2 = g.send("apple") #yield="apple";first=yield
print(res2)
################
first line
1
second line apple
2

生产者消费者实例

def consumer(name): #定义一个消费者的生成器函数
    print("the %s come in"%name)
    while True:
        apple = yield #每执行一次循环暂停一次
        print("%s eat an [%s]"%(name,apple))

def producer(): #定义一个生成者函数
    c1 = consumer("Jack") #消费者迭代器
    next(c1) 
    #进行第一次迭代,打印"the Jack come in"
    #返回值为none
    for i in range(5):
        c1.send("apple%d"%i)
        #进行苹果生产,for循环共循环5次,加上第一次迭代总共迭代6次
        #apple1值赋给apple变量,并执行打印字符串操作

producer()
#the Jack come in
#Jack eat an [apple0]
#Jack eat an [apple1]
#Jack eat an [apple2]
#Jack eat an [apple3]
#Jack eat an [apple4]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值