xone

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

 

迭代器
迭代是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
1. 可迭代对象
以直接作用于 for 循环的数据类型有以下几种:
一类是集合数据类型,如 list 、 tuple 、 dict 、 set 、 str 等;
一类是 generator ,包括生成器和带 yield 的generator function。
这些可以直接作用于 for 循环的对象统称为可迭代对象: Iterable 。
2. 判断是否可以迭代
可以使用 isinstance() 判断一个对象是否是 Iterable 对象:

In [50]: from collections import Iterable

In [51]: isinstance([], Iterable)
Out[51]: True

In [52]: isinstance({}, Iterable)
Out[52]: True

In [53]: isinstance('abc', Iterable)
Out[53]: True

In [54]: isinstance((x for x in range(10)), Iterable)
Out[54]: True

In [55]: isinstance(100, Iterable)
Out[55]: False

  

3.迭代器

可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。

可以使用 isinstance() 判断一个对象是否是 Iterator 对象:

In [56]: from collections import Iterator

In [57]: isinstance((x for x in range(10)), Iterator)
Out[57]: True

In [58]: isinstance([], Iterator)
Out[58]: False

In [59]: isinstance({}, Iterator)
Out[59]: False

In [60]: isinstance('abc', Iterator)
Out[60]: False

In [61]: isinstance(100, Iterator)
Out[61]: False

 

总结

凡是可作用于 for 循环的对象都是 Iterable 类型;
凡是可作用于 next() 函数的对象都是 Iterator 类型
集合数据类型如 list 、 dict 、 str 等是 Iterable 但不是 Iterator ,不过可以通过 iter() 函数获得一个 Iterator 对象。

 

⽣成器
1. 什么是⽣成器
通过列表⽣成式,我们可以直接创建⼀个列表。但是,受到内存限制,列表 容量肯定是有限的。⽽且,创建⼀个包含100万个元素的列表,不仅占⽤很 ⼤的存储空间,如果我们仅仅需要访问前⾯⼏个元素,那后⾯绝⼤多数元素 占⽤的空间都⽩⽩浪费了。所以,如果列表元素可以按照某种算法推算出 来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必 创建完整的list,从⽽节省⼤量的空间。在Python中,这种⼀边循环⼀边计算 的机制,称为⽣成器:generator。
2. 创建⽣成器⽅法1
要创建⼀个⽣成器,有很多种⽅法。第⼀种⽅法很简单,只要把⼀个列表⽣ 成式的 [ ] 改成 ( )

In	[15]:	L	=	[	x*2	for	x	in	range(5)]
In	[16]:	L Out[16]:	[0,	2,	4,	6,	8]
In	[17]:	G	=	(	x*2	for	x	in	range(5))
In	[18]:	G Out[18]:	<generator	object	<genexpr>	at	0x7f626c132db0>
In	[19]:

  

yield

def createNum():
    a = 0
    b = 1
    for i in range(10):
        a,b = b,a+b
        yield b

a = createNum() #这里没有执行这个函数
#调用生成器的方法
#方法一
print("----1----")
print(next(a))  #从这里开始执行这个函数
print(next(a))
print(next(a))
#方法二
print("----2----")
print(a.__next__())
print(a.__next__())
print(a.__next__())
#方法三
print("----3----")
for i in a:
    print(i)

  输出

----1----
1
2
3
----2----
5
8
13
----3----
21
34
55
89

  

send

def test():
    i = 0
    while i < 5:
        temp =yield i
        print(temp)
        i+=1

t = test()
print("---1---")
print(t.__next__())
print("---2---")
print(t.__next__())
print("---3---")
print(t.send("haha")) #这里相当于让yield i = "haha",然后temp = "haha" ,接着运行下面的代码

  输出

---1---
0
---2---
None
1
---3---
haha
2

  

多任务(协程)

def test1():
    while True:
        print("---1---")
        yield None

def test2():
    while True:
        print("---2---")
        yield None

t1 = test1()
t2 = test2()

while True:
    while True:
        t1.__next__()
        t2.__next__()

  

总结
⽣成器是这样⼀个函数,它记住上⼀次返回时在函数体中的位置。对⽣成器 函数的第⼆次(或第 n 次)调⽤跳转⾄该函数中间,⽽上次调⽤的所有局部 变量都保持不变。
⽣成器不仅“记住”了它数据状态;⽣成器还“记住”了它在流控制构造(在命令 式编程中,这种构造不只是数据值)中的位置。
⽣成器的特点:
1. 节约内存 2. 迭代到下⼀次的调⽤时,所使⽤的参数都是第⼀次所保留下的,即是 说,在整个所有函数调⽤的参数都是第⼀次所调⽤时保留的,⽽不是新 创建的

posted on 2019-01-15 17:15  周小百  阅读(141)  评论(0编辑  收藏  举报