python3.4中yield from语句详解

1、可迭代对象与迭代器的区别

可迭代对象:指的是具备可迭代的能力,即enumerable.  在Python中指的是可以通过for-in 语句去逐个访问元素的一些对象,比如元组tuple,列表list,字符串string,文件对象file                                 等。而在.NET中指的是实现了IEnumerable接口的对象,然后可以通过foreach去逐个访问其中的元素。

迭代器:指的是通过另一种方式去一个一个访问可迭代对象中的元素,即enumerator。在python中指的是给内置函数iter()传递一个可迭代对象作为参数,返回的那个对象就是迭代               器,然后通过迭代器的next()方法逐个去访问。在.NET中通过obj.GetEnumerator()方法去得到可迭代对象的迭代器(在.NET中也称之为迭代子),GetEnumerator()方法返               回的就是一个迭代器,然后通过current属性和movenext方法去逐个访问元素。

2、生成器——generator

生成器的本质就是一个逐个返回元素的函数,即“本质——函数”(这里不详细解释什么是生成器了,可以参考我的前面的文章)

生成器有什么好处?

      最大的好处在于它是“延迟加载”,即对于处理长序列问题,更加的节省存储空间。即生成器每次在内存中只存储一个值,比如打印一个斐波拉切数列:原始的方法可以如下所示:

def fab(max): 
    n, a, b = 0, 0, 1 
    L = [] 
    while n < max: 
        L.append(b) 
        a, b = b, a + b 
        n = n + 1 
    return L

这样做最大的问题在于将所有的元素都存储在了L里面,很占用内存,而使用生成器则如下所示

def fab(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b                 #每次迭代时值加载这一个元素,而且替换掉之前的那一个元素,这样就大大节省了内存。而且程序在遇见yield语句时会                                       停下来,这是后面使用yield阻断原理进行多线程编程的一个启发,(python协程编程会在后面讲到)
        a, b = b, a + b
        n = n + 1


生成器其实就是下面这个样子,写得简单一些就是一次返回一条,如下:

def generator():
for i in range ( 5 ):
yield i

def generator():
yield 1
yield 2
yield 3
yield 4
yield 5

上面这两种方式是完全等价的,只不过前者更简单一些。


3、什么又是yield from呢?

     简单地说,yield from  generator 。实际上就是返回另外一个生成器。如下所示:

def generator2():
yield 'a'
yield 'b'
yield 'c'
yield from generator1() #yield from iterable本质上等于 for item in iterable: yield item的缩写版
yield from [ 11, 22, 33, 44]
yield from ( 12, 23, 34)
yield from range(3)
从上面的代码可以看书,yield from 后面可以跟的式子有“ 生成器  元组 列表等可迭代对象以及range()函数产生的序列”

上面代码运行的结果为:

for i in generator2():
print(i,end = ' , ')
运行的结果为:

a , b , c , 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 11 , 22 , 33 , 44 , 12 , 23 , 34 , 0 , 1 , 2 ,


      

你可能感兴趣的:(python)