生成器&迭代器

列表生成器
def f(n):
    return n*2

a = [f(n) for n in range(10)]
a1 = [n*n for n in range(10)]
print (a)
print (a1)
print (type(a)) 输出结果: [0, 1, 8, 27, 64] [0, 1, 4, 9, 16] <type 'list'> ---------------------------------------------------- t = ("123",8) a,b = t #相当于a = t[0],b = [t1] a,b,c = t#报错,赋值个数要与元组个数相同 print (a) print (b) 输出结果: 123 8 ----------------------------------------------------- s = (x*2 for x in range(3)) print (s) 输出结果: <generator object <genexpr> at 0x0255A990>#生成器的内存地址 print next(s) # python2 s._next_() print next(s)#调用next的方式取值 print next(s) print next(s)#这句报错 StopIteration,不能超固定范围 输出结果: 0 2 4 ---------------------------------------------------------- s = (x*2 for x in range(3)) for i in s: print (i) 输出结果: 0 2 4 注: 1、for 会自动调用内部的next() 2、for 会判断并且处理StopIteration异常 ----------------------------------------------------------- def foo():#这是一个普通的函数 print ("ok") renturn 1 foo()
-----------------------------------------------------------
def foo():#这是一个生成器函数,因为有yield print ("ok") yield 1#只要有yield就是一个生成器对象,否则就是一个普通函数 foo()#是一个生成器对象,类似一个做菜厨师 g = foo() print g print next(g)#取到一个1 输出结果: <generator object foo1 at 0x0254A990> ok 1 ------------------------------------------------------------- def foo(): #相当于厨师会做两道菜,如果点第三道菜就会报错一个yield是一道菜 print ("ok") yield 1 print ("ok") yield 2 g = foo()
next(g)这只能打印出OK,不能打印出1,因为没有打印返回值
next(g)这只能打印出OK2,不能打印2,因为没有打印返回值
print (next(g))#做出的第一道菜,返回1 print (next(g))#做出的第二道菜,返回2 print (next(g))#再继续让厨师做菜就会报错了 输出结果: ok 1 ok1 2 --------------------------------------------- 使用for 循环取值 def foo(): print ("ok") yield 1 print ("ok1") yield 2 for i in foo(): print i 输出结果: ok 1 ok1 2 --------------------------------------------------- for 循环遍历可迭代对象。 什么是可迭代对象?是指拥有iter方法的对方叫可迭代对象(Iterable) 如: #列表 a = [1,2,3] a._iter_() #元组 t = (1,2,3) t._iter_() #字典 d = {"name":"guo"} d._iter_()

 

非波拉那契
def fib(max):
    n ,berfore ,after = 0,0,1
    while n<max:
        print(berfore)
        berfore ,after = after ,berfore+after
        n = n+1
fib(6)
输出结果:
0
1
1
2
3
5
---------------------------------------------------------
把print改成yield 就成了一个生成器函数了
def fib(max):
    n,berfore,after = 0,0,1
    wile n<max:
        yield berfore
    n=n+1
print (fib(8))#拿到的还是生成器对象地址
g = fib(8) #这里已经决定只能生成多少个值,超过就会报错
print next(g)#取值方法
print next(g)
pirnt next(g)
print next(g)
输出结果:
<generator object fib1 at 0x0266A788>
0
1
1
2
----------------------------------------------------------
生成器有一个next方法
def bar():
    print("ok")
    count = yield 1
    print (count)
    
    yield 2
 
b =  bar()#生成一个生成器对象
print (b.send(None))# 相当于了b.next()
print (b.send("oooo"))#会将"oooo"传给yield前面的变量count.
输出结果:
ok
1
oooo
2

"""
send()跟next()是一样的,只不过send()可以向函数体传值,传给yield前面的变量。
#send第一次进函数体时,只能传一个空值进去,因为他不知道传给谁
第一次进函数体时,可以用next(),可以代替send()传空值
"""
---------------------------------------------------------------------
生成器都是迭代器,迭代器不一定是生成器
l = [1,2,3,4]#这是一个可迭代对象
d = iter(l)#通过iter转换为迭代器
print (d)
输出结果:
<listiterator(迭代器) object at 0x0248EE10>
-------------------------------------------
什么是可迭代器?满足两个条件。
1、有Iter()方法
2、有next()方法

for i in [1,2,3,4]:# 列表是一个可迭代对象
    iter([1,2,3,4])#将列表转换成一个迭代器对象
"""
1、凡可用作于for循环的对象都是Iterable(可迭代对象)
2、凡是可用于next() 的都是Iterator(迭代器)
3、一类是集合数据,如:list,tuple,dict,set,str等,可以通过一个iter()转换成一个迭代器对象
4、 一类是generator( 生成器),包括带yield的generator function(生成器函数)
这些都可以称为迭代器对象(Iterable)
可以使用isinstance()判断是否是Iterable
例:l = [1,2,3,4]
    d = isinstance(l,Iterable)
    print (d)
    输出结果:
    True
"""                 

*-*-*-*-*-*-*-*-*-*-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-

小结:

迭代器是可以记住遍历的位置的对象

迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问结束,只能往前不能后退

迭代器满足两个条件:iter(),next()

字符串,列表,元组,字典,生成器,包括带yield的生成器函数,都可以转换成迭代器

list = [1,2,3,4]#可迭代对象
li = iter(list)#转换成迭代器对象
print next(li)#输出迭代器的第一个元素
print next(li)#输出迭代器的下一个元素
输出结果:
1
2

迭代器对象可用for进行遍历

list = [1,2,3,4]#可迭代对象
li = iter(list)#转换成迭代器对象
for i in li:
    print (i,end = '')
输出结果:
1 2 3 4

生成器

在函数中有yield的函数叫生成器(generator)

生成器就是一个迭代器

在调用函数时,每次遇到yield就会停止,保存所有信息,返回yield的值,下次运行是从这里继续

调用生成器 函数,返回的是一个迭代对象

def fib(max): #生成器函数
    n,b,a = 0,0,1
    while n<max:
        yiel a
        b,a =a,b+a
        n +=1
f = fib(8)#F是一个迭代器,由生成器函数返回生成
for i in f:
    print (i,end = "")
输出结果:
0 1 1 2 3 5 8 13 21
---------------------------------------
也可这种方式取值
import sys
while True:
    try:
        print(next(f,end = ''))
    except:
        sys.exit()
输出结果:
0 1 1 2 3 5 8 13 21

 

posted @ 2018-02-02 22:36  藤上小冬瓜  阅读(143)  评论(0编辑  收藏  举报