Python进阶之路—10

20、迭代器与生成器
(1)、迭代器(iterator)
<1>可迭代对象(interable)
在一个给定的list或tuple中,我们可以通过for循环来遍历这个list或tuple,这种遍历叫做迭代(interation)。
for循环中,遍历的对象,也叫做可迭代对象。例如,list、tuple、dict、set、str等。
<2>可迭代对象与迭代器的对比
举例:

Li = [1,2,3,4]
y = iter(Li)
print(next(y))#1
print(next(y))#2
print(type(y))#<class 'list_iterator'> 列表生成器类型    

说明:程序中,变量Li是一个列表,属于可迭代对象,可以实现iter方法(或者说,可调用iter()函数)。变量y则是是一个迭代器,可调用next()函数。
<3>迭代器
迭代器内部持有一个状态,该状态用于记录当前迭代所在的位置,以方便下次迭代的时候获取正确的元素。它能在你调用next()方法的时候返回容器中的下一个值,任何实现了next()(在Python2中实现next())的方法的对象都是迭代器。
通俗点说,满足两个条件就可以
.有iter方法
.有next方法
迭代器的创建:

Li = [1,2,3,4]
y = iter(Li)#y就变成了一个迭代器
print(next(y))#1
print(next(y))#2通过调用next()方法
print(type(y))#<class 'list_iterator'> 列表生成器类型  

说明:每次调用next()方法的时候做两件事:
.为下一次调用next()方法修改状态
.为当前这次调用生成返回结果
迭代器就像是一个懒加载的工厂,等到有人需要的时候才给它生成返回值,没调用的时候就处于休眠状态等待下一次调用。大大的减少了内存的占用。
<4> for i in (itreable)的内部实现
在大多情况下,我们不会一次次调用next方法去取值,而是通过
for i in(itreable)
例如:
这里写图片描述

**注意:**in后面的对象如果是一个迭代器,内部因为有iter方法才可以进行操作,所以,迭代器协议里面有iter和next方法,否则for语句无法应用。

for循环内部三件事:
1、调用可迭代对象的iter方法,返回一个迭代器对象
2、不断调用迭代器对象的next()方法
3、处理stopIteration
(2)、生成器(generator)
<1>生成器其实是一种特殊迭代器。但迭代器不一定是生成器。关键字yield
用生成器来实现斐波那契数列的例子

'''
斐波那契数列: 
            n:0 1 2 3 4 5 6 
            f:0 1 1 2 3 5 8 13 21 
              B A
                B A
                  B A
                    B A
'''
def fib(max):
    n,before,after =0,0,1
    while n < max:
        yield after
        # before, after = after,before + after  #从右往左计算赋值
        temp = before
        before = after
        after = temp + after
        n += 1
for i in fib(5):
    print(i)

说明: fib 就是一个普通的python函数,它特需的地方在于函数体中没有 return 关键字,函数的返回值是一个生成器对象。当执行 f=fib(5) 返回的是一个生成器对象,此时函数体中的代码并不会执行,只有显示或隐示地调用next的时候才会真正执行里面的代码。
yield 的作用就是把一个函数变成一个 generator,带有 yield 的函数不再是一个普通函数,Python 解释器会将其视为一个 generator,在 for 循环执行时,每次循环都会执行 fib 函数内部的代码,执行到 yield after 时,fib 函数就返回一个迭代值,下次迭代时,代码从 yield b 的下一条语句继续执行,而函数的本地变量看起来和上次中断执行前是完全一样的,于是函数继续执行,直到再次遇到 yield。看起来就好像一个函数在正常执行的过程中被 yield 中断了数次,每次中断都会通过 yield 返回当前的迭代值。
<2>Return
在一个生成器中,如果没有return,则默认执行到函数完毕;如果有return,并在在执行过程中遇到return,则直接跳出StopIteration 终止迭代。

def f():
    yield 'ok'
    print('wlecome')
    return
    yield 'haha'
    print('xixi')
f = f()
print(next(f))
print(next(f))
#——————————————————————
for i in f:
     print(i)

说明:执行到第二个print(next(f)),跳出StopIteration 终止迭代。
但是如果,使用for循环,遇到return并没有报错,是因为for内部处理了迭代结束的这种情况。
<3>Send

def bar():
    print('ok1')
    count = yield 1
    print(count)
    print('ok2')
    yield 2
b = bar()#创建生成器对象
b.send(None)#next(b)   第一次send前如果没有next,只能传一个send(None)
c = b.send('hyq')
print(c)

说明:执行到这句b.send(None),等同于next(b),执行流程,打印‘ok1’,遇到yield, 中断执行函数体里内容。然后,跳到c = b.send(‘hyq’),接着从yield执行,并把‘hyq’赋值给count,继续执行接下来的代码,直到再次遇到yield,返回值为2,程序结束。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python进阶之路》是一本非常值得推荐的Python进阶书籍。这本书由一位经验丰富的Python大牛所著,作者拥有超过20年的Python开发经验。这本书涵盖了许多Python进阶知识点,如元编程、动态属性、属性描述符、异步处理等。书中详细列举了这些高级特性的使用方法,并讲解得非常透彻。如果你想从入门迈向进阶,这本书是必备的参考资料。 另外,《Python Cookbook》也是一本非常受欢迎的Python进阶书籍。这本书总结了大量精妙的编程技巧和实用的技术,无论你是Python新手还是老手,都会从中收获很多。豆瓣评分高达9.2分,可见其受到广大读者的认可。 除了以上两本书,《Python进阶技巧》也是一本非常值得一读的进阶书籍。这本书的作者将许多代码简化成了一行,展现了Python的高级技巧。虽然有些地方可能看起来有些夸张,但它确实帮助你了解Python的特性和一些不错的功能。而且,在关键时刻,这种技巧还可以让你轻松搞定其他人需要十几行代码才能完成的任务。对于想要进阶的同学来说,这本书的阅读是非常适合的。 总而言之,《Python进阶之路》、《Python Cookbook》和《Python进阶技巧》都是非常优秀的Python进阶书籍,适合想要深入学习Python的读者。 : 引用自《Python进阶之路》 : 引用自《Python Cookbook》 : 引用自《Python进阶技巧》

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值