生成器(yield [from]) --使用的两个例子

使用示例1:创建处理数据的管道

具体描述:我们想以流水线式的形式对数据进行迭代处理(类似Unix下的管道)。比方说我们有海量的数据需要处理,但是没法完全的将数据加载到内存中去。

解决方案:生成器函数是一种实现管道机制的好方法(具体代码不做描述了,这里简单介绍下原理)

原理剖析:
1、yield语句表现为数据的生产者,for循环表现为数据的消费者;
2、由于处理过程的迭代特性,这里只会用到非常少的内存。

使用示例2:我们有一个嵌套序列,想将它扁平化处理为一列单独的值

解决方案:通过写一个带有yield from语句的递归生成器函数来解决
import collections
def flatten(items, ingore_types=(str, bytes)):
    for x in items:
        # isinstance(x, collections.Iterable) 检查是否有某个元素是可迭代的;
        # 如果有,那么就用yield from将这个可迭代对象作为一种子例程进行递归,它将所有的值都产生出来
        if isinstance(x, collections.Iterable) and not isinstance(x, ingore_types):
            # not isinstance(x, ingore_types)是为了避免将字符串和字节串解释为可迭代对象,进而将他们展开为单独的一个个字符
            yield from flatten(x)
        else:
            yield x

items = [1, 2, [3, 4, [5, 6], 7], 8]
for x in flatten(items):
    print(x)
    
1
2
3
4
5
6
7
8

关于为何过滤not isinstance(x, ingore_types), 实例如下:

items = ['Dave', 'Paula', ['Thomas', 'Lewis']]
for x in flatten(items):  # 输出了整个字符串(并没有迭代字符串)
    print(x)
    
Dave
Paula
Thomas
Lewis
总结:

如果想编写生成器用来把其他的生成器当做子例程来调用,yield from是个不错的快捷方式。

你可能感兴趣的:(生成器(yield [from]) --使用的两个例子)