• 《流畅的python》— 列表推导与生成器表达式


    列表推导是构建列表(list)的快捷方式,而生成器表达式则可以用来创建其他任何类型的序列。如果你的代码里并不经常使用它们,那么很可能你错过了许多写出可读性更好且更高效的代码的机会。

    很多Python 程序员都把列表推导(list comprehension)简称为listcomps,生成器表达式(generator expression)则称为genexps。我有时也会这么用。

    1、列表推导

    >>> symbols = '$¢£¥€¤'
    >>> codes = [ord(symbol) for symbol in symbols]
    >>> codes
    [36, 162, 163, 165, 8364, 164]

    for 循环可以胜任很多任务:遍历一个序列以求得总数或挑出某个特定的元素、用来计算总和或是平均数,还有其他任何你想做的事情。在示例2-1 的代码里,它被用来新建一个列表。

    另一方面,列表推导也可能被滥用。以前看到过有的Python 代码用列表推导来重复获取一个函数的副作用。通常的原则是,只用列表推导来创建新的列表,并且尽量保持简短。如果列表推导的代码超过了两行,你可能就要考虑是不是得用for 循环重写了。就跟写文章一样,并没有什么硬性的规则,这个度得你自己把握。

    2、生成器表达式

    虽然也可以用列表推导来初始化元组、数组或其他序列类型,但是生成器表达式是更好的选择。这是因为生成器表达式背后遵守了迭代器协议,可以逐个地产出元素,而不是先建立一个完整的列表,然后再把这个列表传递到某个构造函数里。前面那种方式显然能够节省内存。

    生成器表达式的语法跟列表推导差不多,只不过把 方括号换成圆括号 而已。下面这个示例展示了如何用生成器表达式建立元组和数组。

    >>> symbols = '$¢£¥€¤'
    >>> tuple(ord(symbol) for symbol in symbols) # ➊
    (36, 162, 163, 165, 8364, 164)
    >>> import array
    >>> array.array('I', (ord(symbol) for symbol in symbols)) # ➋
    array('I', [36, 162, 163, 165, 8364, 164])

    ➊ 如果生成器表达式是一个函数调用过程中的唯一参数,那么不需要额外再用括号把它围起来。
    ➋ array 的构造方法需要两个参数,因此括号是必需的。array 构造方法的第一个参数指定了数组中数字的存储方式。2.9.1 节中有更多关于数组的详细讨论。

    下面这个示例则是利用生成器表达式实现了一个笛卡儿积,用以打印T恤衫的 2 种颜色和 3 种尺码的所有组合。与上一个示例不同的是,用到生成器表达式之后,内存里不会留下一个有 6 个组合的列表,因为生成器表达式会在每次 for 循环运行时才生成一个组合。如果要计算两个各有 1000 个元素的列表的笛卡儿积,生成器表达式就可以帮忙省掉运行 for 循环的开销,即一个含有 100 万个元素的列表。

    >>> colors = ['black', 'white']
    >>> sizes = ['S', 'M', 'L']
    >>> for tshirt in ('%s %s' % (c, s) for c in colors for s in sizes): # ➊
    ... print(tshirt)
    ...
    black S
    black M
    black L
    white S
    white M
    white L

    生成器表达式逐个产出元素,直接计算到最后一个元素,从来不会一次性产出一个含有6 个T 恤样式的列表。


    3、总结:两者区别

    • 生成器表达式每次处理一个对象,而不是一口气处理和构造整个数据结构,这样做可以节省大量的内存,在处理的数据量较大时,最好考虑使用生成器表达式而不是列表推导式;
    • 得到的值不一样,列表推导式得到的是一个列表,生成器表达式获取的是一个生成器,但是你可以遍历输出。而且列表推导式可以多次迭代,生成器表达式只能单次迭代。
  • 相关阅读:
    C++--智能指针--1123
    数据库(18)——DCL权限控制
    【Linux升级之路】6_进程间通信
    Kotlin协程:Flow基础原理
    emacs从缓冲中获取信息,并执行shell 命令
    Cache学习(1):常见的程序运行模型&多级Cache存储结构
    金x软件有限公司安全测试岗位面试
    logstash 通配日期目录
    BSV 上用于通用计算的隐私非交互式赏金
    python rb读取文件 base64加密 byte.decode解密,base64解密
  • 原文地址:https://www.cnblogs.com/chenxyy/p/17653510.html