迭代器生成器和协程函数

迭代器

只要对象本身有__iter__方法,那么它就是可迭代对象
1.迭代器提供了一种不依赖引索的取值方式,用于遍历那些没有引索的可迭代对象(字典,集合,文件)

2.迭代器与列表比较,迭代器更省内存。

缺点:无法获取迭代器的长度,不如列表引索取值灵活。

迭代器只能一次取值

# 迭代器 while取值
d = ["a", "b", "c", "d", "e"]
i = d.__iter__()
while True:
    try:
        print(i.__next__())
    except StopIteration:
        break

迭代器用for取值

# 迭代器
d = ["a", "b", "c", "d", "e"]
i = iter(d)
# print(next(i))
# print(i.__next__())
# print(next(i))
for k in i:
    print(k)

查看可迭代对象和迭代器对象

# 查看可迭代对象与迭代器对象
from collections import Iterator,Iterable
s = "abc"
l = ["a", "b", "c"]
t = ("a", "b", "c")
d = {"a": 1, "b": 2, "c": 3}
set1 = {"a", "b", "c"}
f = open("a.txt")

print(isinstance(s, Iterable))    # True 是可迭代对象
print(isinstance(l, Iterable))    # True
print(isinstance(t, Iterable))    # True
print(isinstance(d, Iterable))    # True
print(isinstance(set1, Iterable)) # True
print(isinstance(f, Iterable))    # True

print(isinstance(s, Iterator))     # False   不是迭代器
print(isinstance(l, Iterator))     # False
print(isinstance(t, Iterator))     # False
print(isinstance(d, Iterator))     # False
print(isinstance(set1, Iterator))  # False
print(isinstance(f, Iterator))     # True

生成器

生成器就是一个函数,这个函数包含yield关键字
yield和return的区别

return只能返回一次值,函数就结束了

yield能返回多次值

生成器的优点
1.yield能把自定义函数做成序列对象。
2.生成器使用yield语句返回一个值。yield语句挂起该生成器函数的状态,保留足够的信息,以便之后从它离开的地方继续执行

3.对于生成器,Python会自动实现迭代器协议,以便应用到迭代背景中(如for循环,sum函数)。由于生成器自动实现了迭代器协议,所以,我们可以调用它的next方法,并且,在没有值可以返回的时候,生成器自动产生StopIteration异常.

# 生成器
def test():
    print("one")
    yield 1
    print("two")
    yield 2
    print("three")
    yield 3
    print("four")
    yield 4


g = test()
print(next(g)) 
next(g)   # 此时函数运行到yield 3停止,返回2,并没有打印。
print(next(g))
print(next(g))
# one
# 1
# two
# three
# 3
# four
# 4

生成器生成杨辉三角

# 生成器生成杨辉三角
# [1]
# [1, 1]
# [1, 2, 1]
# [1, 3, 3, 1]
# [1, 4, 6, 4, 1]
# [1, 5, 10, 10, 5, 1]
# [1, 6, 15, 20, 15, 6, 1]
# [1, 7, 21, 35, 35, 21, 7, 1]
# [1, 8, 28, 56, 70, 56, 28, 8, 1]
# [1, 9, 36, 84, 126, 126, 84, 36, 9, 1]

def triangles():
    l = [1]
    while True:
        yield l
        l = [l[x]+l[x+1]for x in range(len(l)-1)]
        l.append(1)
        l.insert(0, 1)
        if len(l) > 10:
            break
g = triangles()
print(g)
for i in g:
    print(i)
    

协程函数

# 协程函数
def eater(name):
    print("%s start to eat food" %name)
    while True:
        food = yield
        print("%s get %s ,to start eat" % (name, food))

e = eater("邹")
# next(e)          # 邹 start to eat food
# e.send("包子")  # 邹 get 包子 ,to start eat
# e.send("馒头")  # 邹 get 馒头 ,to start eat
# e.send("辣条")  # 邹 get 辣条 ,to start eat

print(next(e))
print(next(e))
print(next(e))

# 邹 start to eat food
# None
# 邹 get None ,to start eat
# None
# 邹 get None ,to start eat
# None

协程函数与列表应用

def eater(name):
    print("%s start to eat food" %name)
    food_list = []
    while True:
        food = yield food_list
        print("%s get %s ,to start eat" % (name, food))
        food_list.append(food)

e = eater("邹")
next(e)          # 邹 start to eat food
print(e.send("包子"))  # 邹 get 包子 ,to start eat['包子']
print(e.send("馒头"))  # 邹 get 馒头 ,to start eat['包子', '馒头']
print(e.send("辣条"))  # 邹 get 辣条 ,to start eat['包子', '馒头', '辣条']
posted @ 2017-04-11 17:06  pirate邹霉  阅读(182)  评论(1编辑  收藏  举报