美文网首页Python
生成器(yield [from]) --使用的两个例子

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

作者: cook__ | 来源:发表于2018-10-03 20:55 被阅读11次

    使用示例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]) --使用的两个例子

        本文链接:https://www.haomeiwen.com/subject/fthtaftx.html