迭代器&生成器

可迭代对象指的是内置有__iter__方法的对象,即obj.__iter__,
  包括序列类型如:字符串、列表、元组
  无序列类型如:字典、集合、文件
x='he'
# print(dir(x)) #查看x可以调用的方法
iter_test=x.__iter__()  #把可迭代对象生成迭代器

print(iter_test)
print(iter_test.__next__())  #》:h
print(iter_test.__next__())  #》:e
print(iter_test.__next__())  #>>:报错

迭代器在执行到最后一个后会报错以终止迭代

for 循环

l=[1,2,3]
for i in l:  #i_l=l.__iter_()    i_l.__next__()
    print(i)

for循环做了两件事
1、把可迭代对象转成迭代器,处理每一个元素
2、抓住错误并处理掉

用while模拟for循环

1 l=[1,2,3,4,5]
2 diedai_l=l.__iter__()
3 while True:
4     try:
5         print(diedai_l.__next__())
6     except StopIteration:       
7         break  # '迭代完毕,循环终止'

python内置next函数

l=['die','erzi','sunzi','chongsunzi']
iter_l=l.__iter__()

print(iter_l.__next__())
#next()---->iter_l.__next__()
print(next(iter_l)) #==print(iter_l.__next__())
>>>:die 
  erzi

生成器:可理解为一种数据类型,这种数据类型自动实现迭代器协议,其他数据类型需调用自己内置的__iter__方法

1、生成器函数

  yield替代return(但是一个函数中yield可以有多个),yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次从离开它的地方继续执行

 1 import time
 2 def test():
 3     print('开始生孩子啦。。。。。。')
 4     yield '' #return
 5     time.sleep(1)
 6     print('开始生儿子啦')
 7     yield '儿子出生了'
 8 
 9     time.sleep(2)
10     print('开始生孙子啦')
11     yield '孙子出生了'
12 
13 res=test()
14 print(res)
15 print(res.__next__()) #调用一次test()
16 print(res.__next__()) #test()
17 print(res.__next__()) #test()
View Code

 

2、生成器表达式

  类似于列表推导,但是生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表

1 ls = [i for i in range(10)] #列表生成式
2 print(ls)
3 >>>:[0,1,2,3,....]
4 
5 
6 ls_g = (i for i in range(10)) #生成器表达式
7 print(ls_g.__next__())
8 >>>:0

 

3、生成器的优点

  提供延迟操作:在需要的时候才产生结果,而不是立即产生结果

yield()和send()

send也可触发生成器,并且能给yield传一个参数

  触发生成器三种方式:1、a.__next__()   2、next(a)  3、a.send(参数)

#通过生成器实现协程并行运算
import time
def consumer(name):
    print("%s 准备吃包子啦!" %name)
    while True:
       baozi = yield 1

       print("包子[%s]来了,被[%s]吃了!" %(baozi,name))


def producer(name):
    c = consumer('A')   #获取一个生成器,此处不会触发函数consumer()
    c2 = consumer('B')
    print( c.__next__())  #触发生成器才会执行consumer(),并且遇到yield时中止,等待下一次触发生成器
    print(c2.__next__())
    print("老子开始准备做包子啦!")
    for i in range(10):
        time.sleep(1)
        print("做了2个包子!")
        c.send(i)
        c2.send(i)

producer("eric")

注意:

刚获取的生成器是空的,遍历过一遍后也是空的

 

 1 def test():
 2     for i in range(4):
 3         yield i
 4 t=test()
 5 
 6 t1=(i for i in t)
 7 t2=(i for i in t1)
 8 print(list(t1))
 9 print(list(t2))
10 
11 >>>:[0, 1, 2, 3]
12     []

三元表达式

三元表达式
name='alex'
#name='linhaifeng'
res='SB' if name == 'alex' else '帅哥'
print(res)

列表解析

l=['鸡蛋%s' %i for i in range(10)]
# l1=['鸡蛋%s' %i for i in range(10) if i > 5 ]

 

posted @ 2018-04-25 10:17  web123  阅读(143)  评论(0编辑  收藏  举报