一、定义与作用

  1、定义:迭代也是一种循环,但是这种循环每次都是基于上一次的结果而继续,并非单纯重复,迭代器就是执行迭代的工具。

  2、作用:迭代器是用来迭代取值,把可迭代对象的值循环取出来。使用迭代器取值,不仅可以用于列表,字符串,元组这些有索引的数据类型,也可以用于字典,集合,文件句柄这种些无索引的数据类型。

二、使用方法

  1、可迭代对象:但凡可以用内置的.__iter__()的方法的对象即为可迭代对象。

  2、迭代器对象:使用,可迭代对象.__iter__()的方法即可以生成迭代器对象。

  3、迭代器取值:使用,迭代器对象.__next__()的方法可以对迭代器对象取值,每调用此方法一次,取出一个可取值,直到所有可取值取完,继续调用的结果会抛出异常StopIteration。

d = {'a': 11, 'b': 2, 'c': 3}
d_iter = d.__iter__()  # 通过可迭代对象字典 d 生成迭代器 d_iter
print(d_iter.__next__())  # 取出迭代器的第一个可取值,结果为 a
print(d_iter.__next__())  # 取出迭代器的第二个可取值,结果为 b
print(d_iter.__next__())  # 取出迭代器的第三个可取值,结果为 c
print(d_iter.__next__())  # 迭代器的可取值已被取完,抛出异常 StopIteration

  4、try...except:终止信号。

d = {'a': 11, 'b': 2, 'c': 3}
d_iter = d.__iter__()
while 1:
    try:
        print(d_iter.__next__())
    except StopIteration:  # 检索异常信号,出现则停止循环
        break

  5、可迭代对象和迭代器对象的关系:

    ①可迭代对象:可使用.__iter__()生成迭代器,无法用.__next__()取值。

    ②迭代器对象:可使用.__iter__()生成迭代器本身,等于没有操作,也可使用.__next__()取值。

    ③总结:可迭代对象未必是迭代器对象,迭代器对象一定是可迭代对象。

  6、文件的特殊性:列表,字符串,元组,字典,集合都只是可迭代对象,而文件句柄是迭代器对象。

  7、for循环的工作原理:迭代器循环。

    ①第一步:对in后面的对象使用.__iter__()生成迭代器对象。

    ②第二布:对迭代器对象使用.__next__()取一个可取值赋值给for后面的变量名。

    ③第三步:重复第二步,直到捕捉到StopIteratino信号则结束循环。

    ④生成某些可迭代对象的功能:如list('abc')的结果是['a'','b','c']。原理同于for循环。

三、迭代器的优缺点

  1、优点:

    ①为有序类型和无序类型的数据提供了统一的迭代取值方式。

    ②惰性计算:迭代器对象表现的功能相当于一个数据流,可以只是需要时才去使用.__next__()取一个值,迭代器本身在内存中只是一个单纯的功能,占的内存微乎其微,无论数据流多大,对迭代器本身大小并无影响,而列表等类型的数据,因为需要把自身元素都存于内存中,受限于内存的大小,元素的个数是有限的。

  2、缺点:

    ①无法通过获取迭代自身的长度而得知数据流的大小,或者说迭代器自身是没有长度的。

    ②每次只能取下一个值,不可以返回取值,也就是说同一个迭代器的每个可取值只能被取一次,取完所有可取值迭代器则无法再被取值,若要再取值,需使用.__iter__()重新生成新的迭代器。

四、生成器

  1、定义:相比于通过对可迭代对象使用.__iter__()生成的迭代器对象,还可以通过函数内定义yield关键字,再通过调用该函数获得其返回值生成自定义的迭代器,生成器即是此种自定义的迭代器。

  2、yield:yield用于返回值,但不同于return,函数一旦遇到return会立即结束执行,而yield会将函数挂起在当前状态,所以当函数体内有yield关键字,可以认为该函数就是用来生成生成器的,此时直接调用函数的话不会产生函数体代码的执行结果,需要把函数调用的结果返回作为生成器使用。

  3、使用:通过对生成器使用.__next__()会触发函数体代码的运行,直到遇到一个yield停下来,返回yield后面的值,再次使用.__next__()则在上次的位置向下继续按照此流程执行。

  4、用生成器模拟range功能生成的数列迭代器:

def define_range(star, end, step):
    while star < end:
        yield star
        star += step
num_iter = define_range(3, 9, 1)
for a in num_iter:
    print(a)  # 结果是 3 4 5 6 7 8 

 

 

posted on 2020-01-03 13:01  焚音留香  阅读(177)  评论(0编辑  收藏  举报