Python 迭代器和生成器
1、迭代器
迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退,迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件
特点:
- 访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容
- 不能随机访问集合中的某个值 ,只能从头到尾依次访问
- 访问到一半时不能往回退
- 便于循环比较大的数据集合,节省内存
创建一个迭代器:
name = iter(['evescn', 'root', 'gmkk'])
print(name)
print(name.__next__())
print(name.__next__())
print(name.__next__())
print("-------------------")
# 如何迭代的读入文件
f = open("test.txt")
for line in f:
print(line.strip())
# 输出结果
<list_iterator object at 0x00000000027CA8D0>
evescn
root
gmkk
--------------------
evescn
root
gmkk
2、生成器 generator
如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。
要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:
g = (x * x for x in range(10))
for i in g:
print(i)
# 输出结果
0
1
4
9
16
25
36
49
64
81
定义:一个函数调用时返回一个迭代器,那这个函数就叫做生成器(generator),如果函数中包含yield语法,那这个函数就会变成生成器
创建一个生成器:
def cash_money(amount):
while amount > 0:
amount -= 100
print("又来取钱了")
yield 100
# print("又来取钱了")
atm = cash_money(500)
print(type(atm))
print("取走了", next(atm))
print("取走了", next(atm))
print("取走了", next(atm))
print("取走了", next(atm))
print("取走了", next(atm))
# 输出结果
<class 'generator'>
又来取钱了
取走了 100
又来取钱了
取走了 100
又来取钱了
取走了 100
又来取钱了
取走了 100
又来取钱了
取走了 100
yield的作用:可以使函数中断,并保存中断状态,中断后,代码可以继续往下执行,重新调用这个函数时,从上次yield(中断)的下一句开始执行。
3、yield 在单线程下实现并发运算的效果
import time
def consumer(name):
print("%s准备吃包子了" %name)
while True:
baozi = yield
print("第%s盘包子来了,包子被%s吃了" %(baozi, name))
def producer(name):
c1 = consumer("evescn")
c2 = consumer("gmkk")
c1.__next__()
c2.__next__()
print("厨师开始做包子了")
for i in range(10):
time.sleep(1)
print("做了2个包子")
c1.send(i+1)
c2.send(i+1)
producer("root")
# 输出结果
evescn准备吃包子了
gmkk准备吃包子了
厨师开始做包子了
做了2个包子
第1盘包子来了,包子被evescn吃了
第1盘包子来了,包子被gmkk吃了
做了2个包子
第2盘包子来了,包子被evescn吃了
第2盘包子来了,包子被gmkk吃了
做了2个包子
第3盘包子来了,包子被evescn吃了
第3盘包子来了,包子被gmkk吃了
做了2个包子
第4盘包子来了,包子被evescn吃了
第4盘包子来了,包子被gmkk吃了
做了2个包子
第5盘包子来了,包子被evescn吃了
第5盘包子来了,包子被gmkk吃了
做了2个包子
第6盘包子来了,包子被evescn吃了
第6盘包子来了,包子被gmkk吃了
做了2个包子
第7盘包子来了,包子被evescn吃了
第7盘包子来了,包子被gmkk吃了
做了2个包子
第8盘包子来了,包子被evescn吃了
第8盘包子来了,包子被gmkk吃了
做了2个包子
第9盘包子来了,包子被evescn吃了
第9盘包子来了,包子被gmkk吃了
做了2个包子
第10盘包子来了,包子被evescn吃了
第10盘包子来了,包子被gmkk吃了
标签:gmkk,迭代,Python,生成器,next,evescn,print,包子
From: https://www.cnblogs.com/evescn/p/17494419.html