列表生成器&生成器&迭代器

---恢复内容开始---

列表生成器

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两种方式:

  1. 把[ ]换成()
  2. 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循环的数据类型有以下几种:

一类是集合数据类型,如listtupledictsetstr等;

一类是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类型,它们表示一个惰性计算的序列;

集合数据类型如listdictstr等是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))

 

posted @ 2018-10-10 12:27  bobo9425861  阅读(160)  评论(0编辑  收藏  举报