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