python中的迭代器和生成器

情到浓时终转凉″ 提交于 2019-12-03 03:23:37

自学python过程中会遗漏一些东西,当初看书的时候碰到这些都跳过了,在一次面试中被问到了生成器,才意识到它在使用中的重要性,然后重新翻回去看了书并总结如下。

1、迭代器(Iterator)

在Python中的for循环使用的就是迭代器的机制,与C语言的循环有所不同。由于使用了迭代器,for循环除了支持常见的序列(元组、列表)外,还支持字典和文件对象。对于任何的可迭代对象都有一个iter方法,使用iter之后函数返回的就是一个迭代器对象,得到迭代器对象后就可以不断使用next方法得到他的下一个值,直到所有值都取完之后返回StopIteration异常。for循环内部实现就是这样的一个过程,并且它自动处理了StopIteration异常,使用更加方便。

dic = {'a':1, 'b':2, 'c':3}
iter_test = iter(dic)
print(next(iter_test))     //print(iter_test.__next__())
print(next(iter_test))     //print(iter_test.__next__())
print(next(iter_test))     //print(iter_test.__next__())
print(next(iter_test))     //print(iter_test.__next__())                                                    

a
b
c
Traceback (most recent call last):
  File "xxx.py", line 7, in <module>
    print(next(iter_test))
StopIteration

上面一个很简单的例子,字典为可迭代对象,使用iter返回迭代器对象后不断调用next得到下一个值(使用next或者__next__都可以)。注意在遍历完字典后会抛出StopIteration异常,如果自己写的话要注意使用try/except语句进行处理。如果仅仅为了遍历可以直接对字典进行for循环,可以减少异常处理流程。不过迭代器在使用中只能不断返回下一个值,不能得到前面的值。

2、生成器(generator)

从使用上看生成器是一种可迭代对象同时也是一种迭代器。对于生成器可以直接使用next或者__next__方法来得到下一个值。生成器主要是用于产生一个序列可用于迭代处理的一种实现方法。如果数据量很大的话,使用列表之类的对象处理需要一下把所有数据都存储下来,而生成器在每次调用的时候返回一个值,同时记录执行的情况在下次调用的时候再次返回下一个值,这样的话就不会占用很大的资源从而提高执行效率。这个也许是生成器的一个合适的定义。其实现方法主要有生成器表达式和yield关键字:

def gene():
    yield 0
    yield 1
    yield 2
    yield 3

a = gene()
print(next(a))
print(next(a))
print(next(a))
print(next(a))
print(next(a))

0
1
2
3
Traceback (most recent call last):
  File "xxx.py", line 13, in <module>
    print(next(a))
StopIteration

从这里看的话生成器跟迭代器的使用是一致的,也会抛出异常。如果使用dir(gene)来看他的方法的话同时有__iter__方法和__next__方法,可以说明生成器也是可迭代对象,尝试用iter(gene)也不会出现错误。下面是生成器表达式的示例,生成器表达式的写法和列表解析的方法类似,只是由方括号改为圆括号:

a = (i for i in range(4))
print(next(a))
print(next(a))
print(next(a))
print(next(a))
print(next(a))

0
1
2
3
Traceback (most recent call last):
  File "xxx.py", line 7, in <module>
    print(next(a))
StopIteration

3、在python内部实现中有很多函数的输入都是可迭代对象(iterable),而生成器也属于一种可迭代对象。python很多内建函如all、any、max、sum、enumerate等,其输入参数都是可迭代对象,因此生成器也可以作为输入参数使用。

a = (i for i in range(4))
print(sum(a))

6

本文仅仅从使用的角度进行总结,对于底层原理的实现暂时还没有深入研究。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!