列表生成器&生成器&迭代器
---恢复内容开始---
列表生成器
a = [i+1 for i in range(10)] print(a) #结果[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
上面就是一个列表生成器
不足:对于数据多的不适用因为太占内存了
生成器
通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator
创建generator两种方式:
- 把[ ]换成()
- yield
a = (i+1 for i in range(10)) print(a)#<generator object <genexpr> at 0x0000000000A777D8> a是一个生成器对象 print(next(a))#对a进行访问 print(next(a)) print(next(a)) print(next(a))
#结果 1 2 3 4
for i in a:#a为生成器对象是可迭代的
print(i)
#结果1 2 3 4 5 6 7 8 9 10
def bar(): print('ok1') count = yield 1 print(count) print('ok2') yield 2 print('ok3') yield 3 f = bar() f.send(None)#等价于next(f) f.send('eeee')#改变yield前面的一个变量前提必须先进行f.send(None)来进行查找变量
迭代器
可以直接作用于for
循环的数据类型有以下几种:
一类是集合数据类型,如list
、tuple
、dict
、set
、str
等;
一类是generator
,包括生成器和带yield
的generator function。
这些可以直接作用于for
循环的对象统称为可迭代对象:Iterable
。
可以使用isinstance()
判断一个对象是否是Iterable
对象:
from collections import Iterable def bar(): print('ok1') count = yield 1 print(count) print('ok2') yield 2 print('ok3') yield 3 f = bar() print(isinstance(f,Iterable))#True是对应的数据类型反之不是
小结:
凡是可作用于for
循环的对象都是Iterable
类型;
凡是可作用于next()
函数的对象都是Iterator
类型,它们表示一个惰性计算的序列;
集合数据类型如list
、dict
、str
等是Iterable
但不是Iterator
,不过可以通过iter()
函数获得一个Iterator
对象。
from collections import Iterable,Iterator l = [1,2,4] l = iter(l) print(type(l)) print(isinstance(l,Iterator)) print(isinstance(l,Iterable)) print(isinstance(l,list))