一、生成器
在生成列表时,可以有一种简单的方法生成一个列表,即为列表生成式
lis = [i*2 for i in range(10)]
如上所示,就是用列表生成式,生成了一个列表。就是将0 到 9依次乘以2然后放入到列表lis中。
但是通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出来后续的元素那?这样不必创建完整的list,从而节省大量的空间。在python中,这种一遍循环一遍计算的机制,成为生成器(generator)。
而且在一定的线程数量下,单线程下的并发运行速度是比开辟实际的线程的速度快的。我们可以用生成器实现单线程下的并发效果。
1、把列表生成式的方式写成生成器
只需要把[ ]变成()就行了
lis = (i*2 for i in range(10))
如此就是一个生成器了。如此只会在调用的时候才会生成相应的数据。
生成器特性
1、生成器只有在调用时才会生成相应的数据
2、生成器只保留当前位置的数据
3、只有__next__()方法。获取下一个数据。
2和3什么意思那。此时调用一下生成器,生成第一个数据。只能使用__next__()来获取数据即
lis.__next__()
lis.__next__()
如上所示,获取了两个数据。此时想要回到第一个数据是没有办法的。只能取下一个数据。
2、将函数变成生成器
首先用函数生成斐波拉契数列(除第一个和第二个数外,任意一个数都可由两个数相加得到。例如[1,1,2,3,4,8,13,21])
此时打印的话就会打印出斐波拉契数列中的数据了。但是如何让这个函数变成一个生成器,每次调用__next__()的时候才会生成一个数据那?在python中有个词为“yield”。如下所示
此时每调用一次__next__(),就会在yield处停止,并返回数据b。“yield”可以让函数停止数次。如果在停止的时候我再做一些别的事情,然后再回来运行这个函数的话。是否就可以实现单线程中的并发效果了。
3、可以通过yield,实现并行效果
yield在python 里就是一个生成器。当你使用一个yield的时候,对应的函数就是一个生成器了。生成器的功能就是在yield的区域进行迭代处理。
现在有这样一个场景,一个饭馆。客户进来之后点了东西,然后在玩手机的同时,饭店也在做着他点的东西。首先先做一个食物生成器,
此时进来顾客之后点了食物,
运行程序
看结果是不是在玩手机的同时,生成器在运行生成食物。其中c.send("张三")可想生成器中传值。与__next__不同,send()可以传值。再将客户优化一下
此时每次有一个客户,就会有个类似并发的线程去生成食物了。如此便实现了单线程下并发的效果。
二、迭代器
1、可迭代对象
可迭代对象(Iterable):可以直接作用于for循环的对象。
1.集合数据类型:如list、tuple、dict、set、str等。
2.生成器
将可迭代对象变为迭代器可用iter()。同时可以用isinstance()来判断是否是迭代对象。
from collections import Iterable
a = [1, 2, 3]
print(isinstance(a, Iterable))
b = iter(a)
print(b.__next__)
2、迭代器
迭代器(Iterator):可以被next()函数调用并不断返回下一个值的对象。
可以用isinstance()来判断是否是迭代器。
from collections import Iterator
b = (i for i in range(10))
print(isinstance(b, Iterator))
代码:https://github.com/zhangyunf/python-.git








网友评论