美文网首页
python 迭代器和生成器

python 迭代器和生成器

作者: SlashMan | 来源:发表于2018-10-17 23:19 被阅读0次

一、生成器

    在生成列表时,可以有一种简单的方法生成一个列表,即为列表生成式

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

相关文章

网友评论

      本文标题:python 迭代器和生成器

      本文链接:https://www.haomeiwen.com/subject/qdarzftx.html