Python学习之迭代器与生成器

迭代: 更新换代的过程
迭代器就是可迭代对象
只要遵循可迭代协议就是可迭代对象
一.什么是迭代器协议
1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前退)

2.可迭代对象:实现了迭代器协议的对象(如何实现:对象内部定义一个__iter__()方法)

3.协议是一种约定,可迭代对象实现了迭代器协议,python的内部工具(如for循环,sum,min,max函数等)使用迭代器协议访问对象。

注:可以通过__next__取值,就是迭代器

迭代是Python最强大的功能之一,是访问集合元素的一种方式。

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

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

迭代器有两个基本的方法:iter() 和 next()

字符串,列表或元组对象都可用于创建迭代器:

#iter()
list=[1,2,3,4]
it = iter(list)    # 创建迭代器对象
print (next(it))   # 输出迭代器的下一个元素  1
print (next(it))                                        2

#迭代器对象可以使用常规for语句进行遍历:
list=[1,2,3,4]
it = iter(list)    # 创建迭代器对象
for x in it:
    print (x, end=" ")               ==》1 2 3 4

也可以使用 next() 函数:
import sys         # 引入 sys 模块
 
list=[1,2,3,4]
it = iter(list)    # 创建迭代器对象
 
while True:
    try:
        print (next(it))
    except StopIteration:
        sys.exit()
输出结果:
1
2
3
4

 (

#三元表达式
name='alex'
res='Sz' if name == 'alex' else '帅哥'             #如果名字等于alex返回前者,否则返回后者
print(res)       ==》Sz

) 

二.python中强大的for循环机制
for循环的本质:循环所有对象,全都是使用迭代器协议。
(字符串,列表,元组,字典,集合,文件对象)这些都不是可迭代对象,只不过在for循环式,调用了他们内部的__iter__方法,把他们变成了可迭代对象

然后for循环调用可迭代对象的__next__方法去取值,而且for循环会捕捉StopIteration异常,以终止迭代

三.什么是生成器?

可以理解为一种数据类型,这种数据类型自动实现了迭代器协议(其他的数据类型需要调用自己内置的__iter__方法),所以生成器就是可迭代对象。

在 Python 中,使用了 yield 的函数被称为生成器(generator)。

跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。

在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。

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

以下实例使用 yield 实现斐波那契数列:
import sys
 
def fibonacci(n): # 生成器函数 - 斐波那契
    a, b, counter = 0, 1, 0
    while True:
        if (counter > n): 
            return
        yield a
        a, b = b, a + b
        counter += 1
f = fibonacci(10) # f 是一个迭代器,由生成器返回生成
 
while True:
    try:
        print (next(f), end=" ")
    except StopIteration:
        sys.exit()

输出结果:
0 1 1 2 3 5 8 13 21 34 55 
#调用方式一(next()):
def f():
    print("ok")
    print("ok2")
    yield

gen=f()
print(gen)  #<generator object f at 0x000000042CB182B0>
next(gen)   #ok
'''
<generator object f at 0x000000042CB182B0>
ok
ok2
'''

#调用方式二(__next__()):
def f():
    print("ok")
    yield 6
    print("ok2")
    yield


gen=f()
RET=gen.__next__()
print(RET)
next(gen)
'''
ok
6
ok2
'''
#调用方式三(send()):
def f():
    print("ok")
    s=yield 6
    print(s)
    print("ok2")
    yield

gen=f()
RET=gen.__next__()
print(RET)

gen.send(5)
'''
ok
6
5
ok2
'''
协程教程之yield()是协程的关键词回顾讲解

 

生成器小结:

1.是可迭代对象

2.实现了延迟计算,省内存啊

3.生成器本质和其他的数据类型一样,都是实现了迭代器协议,只不过生成器附加了一个延迟计算省内存的好处,其余的可迭代对象可没有这点好处,记住喽!!!

更多内容参见:https://www.cnblogs.com/luchuangao/p/6685626.html

 

补充:

 1 l=['a','b','c','d']
 2 def test():
 3     return l.pop()
 4 
 5 x=iter(test,'b')  #运行test函数时遇到b终止
 6 print(x.__next__())
 7 print(x.__next__())
 8 print(x.__next__())
 9 输出:
10 d
11 c
12 StopIteration
13 
14 ******************************************
15 from functools import partial
16 def add(x,y):
17     return x+y
18 
19 func=partial(add,1) #偏函数  :固定函数的第一个参数
20 print(func(1))
21 print(func(2))
22 输出:
23 2
24 3
iter及partial补充

 

posted @ 2018-07-16 17:22  一只小妖  阅读(126)  评论(0)    收藏  举报