Python - 可迭代对象/迭代器/生成器

一 可迭代对象 Iterable
它包含一个__iter__()__getitem__()方法,一般来说,只要提供了__iter__()方法都是iterable(字符串str没有__iter__(),但实现了 __getitem__()方法 )

二 迭代器对象 Iterator
Python3.x 的特色,与Python2.x相比很多函数的返回值类型改成了Iterator.
迭代器对象 要实现两个方法 __iter__()__next__()
迭代器对象,一定是可迭代对象,因为它实现了__iter__()方法)

迭代器对象 的本职工作是来做 next 的,为什么还要实现 __iter__(),返回它自己呢?
一个象容器一样的对象,如果想要可以迭代,就需要实现 __iter__()这个方法。用这个方法,来返回一个迭代器对象,再调用__next__()方法,这样的话,就可以被for in这样的语句来处理,象处理序列一样来处理。

x = [1, 2, 3]
for e in x:
    ...

这里写图片描述

三 生成器对象 gentator
生成器其实就是一种特殊的迭代器,所以迭代器有的生成器也有.
从某种意义上来说可以节约内存.
生成器的产生有两种方式
1 生成器函数
生成器函数使用yield()函数生成.它可以延迟创建值.(使函数可以暂停或者挂起,并可以从暂停处继续运行或重新开始)

>>> def myfun():        
...     print('this code will be run')
...     yield 1
...     yield 2
...     yield 3
... 
>>> a = myfun()
>>> next(a)
this code will be run
1
>>> next(a)
2
>>> next(a)
3
>>> next(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

自定义函数myfun()中有关键字yield说明它一定是一个生成器函数,即返回的是一个生成器对象. 而且这个函数执行到 yield 1的时候就已经暂停了.
yield 关键字可以理解为return但不会终止函数的调用,只是会暂停.
用next()函数可以依次得到生成器的值.直到抛出异常.
生成器当然也可以用for 循环来遍历:

>>> for i in myfun():
...     print(i)
... 
this code will be run
1
2
3

又例如 面试 问到过的斐波拉契数列:
打印出小于100的数.

def fibo():
    a = 0
    b = 1
    while True:
        a, b = b, a+b
        yield a

for i in fibo():
    if i < 100:
        print(i,end=' ')
    else:
        break

2生成器表达式。
生成器表达式与推导式类似。
在另一篇博客介绍了列表推导式和字典推导式,这里再继续介绍生成器推导式.

x = (i for i in range(5))
print(x)
for a in x:
    print(a,end=' ')
#输出
<generator object <genexpr> at 0x10f27b048>
0 1 2 3 4 

用小括号()括起来.
元组(tuple)是不可变的,所以没有元组推导式,所以小括号就只单纯的表示函数推导式,也就是生成器推导式,
同理,字符串(str)也是没有推导式的.
列表推导式用中括号[];集合和字典用大括号{};

猜你喜欢

转载自blog.csdn.net/Yolandera/article/details/80506941