六、迭代器与生成器

1、迭代器协议

  1. 协议:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么引起一个Stoplteration异常,以终止迭代(只能往后不能往前)
  2. 可迭代对象:实现了迭代器协议的对象(如何实现:对象内部定义一个__iter__()方法)
  3. 协议是一种约定,可迭代对象实现了迭代器协议,python的内部工具(如for循环,sum,min,max函数等)使用迭代器协议访问对象。

2、for循环机制

  • 本质:循环所有对象,全部使用迭代器协议
  • for循环:先调用对象的__iter__方法将其转换成一个迭代器,然后使用迭代器协议实现循环访问。
1 # for i in l:    # 相当于:i_l = l.__iter__() ; i_l.__next__()
2 l = [0,1]
3 l_iter = l.__iter__() #生成可迭代对象,遵循迭代器协议
4 print(l_iter.__next__())
5 print(l_iter.__next__())
6 
7 输出:
8 0
9 1
 1 #使用while循环模拟for循环所作的事
 2 l = [1,2,3]
 3 l_test = l.__iter__()
 4 while True:
 5     try:
 6         print(l_test.__next__())
 7     except StopIteration:
 8         print('迭代结束。')
 9         break
10 
11 输出:
12 1
13 2
14 3
15 迭代结束。

3、列表生成式:把要生成的元素放在前面,后面跟 for 循环,把list列表创建出来,后面可加 if 判断或者继续再使用 for

1 #计算列表[1x1, 2x2, 3x3, ..., 10x10]的结果,并能被2整除的数。
2 
3 print(list(x * x for x in range(1,11) if x%2==0))
4 
5 输出:
6 [4, 16, 36, 64, 100]
1 #使用for循环来求值
2 
3 l = []
4 for i in range(1,11):
5     if i % 2 == 0:
6         l.append(i*i)
7 print(l)

4、生成器

  • 一种数据类型,能自动实现迭代器协议(其它需调用自身内置的__iter__方法),所以生成器就是可迭代对象。
  • 两种形式:
      • 1、生成器函数:函数使用yield语句而不是return语句返回,一次返回一个结果,中间挂起函数状态,以便下次从离开的地方执行(yield可返回多次值)
         1 def test():
         2     yield 1
         3     yield 2
         4 f = test()
         5 print(f)
         6 print(f.__next__())    #可直接使用next方法
         7 print(f.__next__())
         8 
         9 输出:
        10 <generator object test at 0x000000D2D88590C0>    #生成迭代器
        11 1
        12 2
      • 2、生成器表达式:类似类表推导,在列表解析的里面用上三元表达式。(将原本生成的列表赋予到一个值中,再从中取值,不直接生成一个列表,减少内存)
    1 #将下文列表解析的 [] 换成(),就是生成表达式。
    2 renwu_list = ('任务%s' %i for i in range(10))
    3 print(renwu_list.__next__())
    4 print(renwu_list.__next__())
    5 
    6 输出:
    7 任务0
    8 任务1
     1 #列表解析
     2 list = ['任务%s' %i for i in range(10)]
     3 print(list)
     4 # list = []
     5 # for i in range(10):
     6 #     list.append('任务%s' %i)
     7 # print(list)
     8 
     9 输出:
    10 ['任务0', '任务1', '任务2', '任务3', '任务4', '任务5', '任务6', '任务7', '任务8', '任务9']
      • 三元表达式
        1 name = 'jack'
        2 res = 'yes' if name == 'jack' else 'no'    #if为True时返回yes
        3 print(res)
        4 
        5 输出:
        6 ye

 5、总结

  • 语法与函数类似;自动生成迭代器协议;状态挂起。
  • 优点:1、延迟计算,一次返回一个结果。2、有效提高代码可读性
  • 注意:生成器只能遍历一遍
原文地址:https://www.cnblogs.com/liqiongming/p/10111196.html