列表推导是构建列表(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、总结:两者区别

  • 生成器表达式每次处理一个对象,而不是一口气处理和构造整个数据结构,这样做可以节省大量的内存,在处理的数据量较大时,最好考虑使用生成器表达式而不是列表推导式;
  • 得到的值不一样,列表推导式得到的是一个列表,生成器表达式获取的是一个生成器,但是你可以遍历输出。而且列表推导式可以多次迭代,生成器表达式只能单次迭代。

《流畅的python》— 列表推导与生成器表达式的更多相关文章

  1. Python骚操作从列表推导和生成器表达式开始

    序列 序列是指一组数据,按存放类型分为容器序列与扁平序列,按能否被修改分为不可变序列与可变序列. 容器序列与扁平序列 容器序列存放的是对象的引用,包括list.tuple.collections.de ...

  2. Python学习笔记2:构造序列:列表推导和生成器表达式

    欢迎访问个人网站:www.comingnext.cn 1. 关于Python内置序列类型 a. 按能否存放不同类型的数据区分 容器序列: list.tuple 和collections.deque这些 ...

  3. Python入门之三元表达式\列表推导式\生成器表达式\递归匿名函数\内置函数

    本章目录: 一.三元表达式.列表推导式.生成器表达式 二.递归调用和二分法 三.匿名函数 四.内置函数 ================================================ ...

  4. python之三元表达式、列表推导、生成器表达式、递归、匿名函数、内置函数

    目录 一 三元表达式 二 列表推到 三 生成器表达式 四 递归 五 匿名函数 六 内置函数 一.三元表达式 def max(x,y): return x if x>y else y print( ...

  5. python 全栈开发,Day14(列表推导式,生成器表达式,内置函数)

    一.列表生成式 生成1-100的列表 li = [] for i in range(1,101): li.append(i) print(li) 执行输出: [1,2,3...] 生成python1期 ...

  6. python之生成器(~函数,列表推导式,生成器表达式)

    一.生成器 概念:生成器的是实质就是迭代器 1.生成器的贴点和迭代器一样,取值方式也和迭代器一样. 2.生成器一般由生成器函数或者声称其表达式来创建,生成器其实就是手写的迭代器. 3.在python中 ...

  7. python基础-三元表达式/列表推导式/生成器表达式

    1.三元表达式:如果成立返回if前的内容,如果不成立返回else的内容 name=input('姓名>>: ') res='SB' if name == 'alex' else 'NB' ...

  8. Python列表解析与生成器表达式

    Python列表解析 l = ["egg%s" %i for i in range(100) if i > 50] print(l) l= [1,2,3,4] s = 'he ...

  9. 2018.11.06 生成器函数进阶&列表推导式&生成器表达式

    1.生成器函数进阶 2.列表推导式 3.生成器表达式

  10. python列表解析和生成器表达式

    列表解析作为动态创建列表的强大工具,值得学习. 列表解析技术之前的状况--函数式编程. lambda.filter(), map() enumerate, sorted, any, all, zip ...

随机推荐

  1. 2021-11-29:给定一个单链表的头节点head,每个节点都有value(>0),给定一个正数m, value%m的值一样的节点算一类, 请把所有的类根据单链表的方式重新连接好,返回每一类的头节点

    2021-11-29:给定一个单链表的头节点head,每个节点都有value(>0),给定一个正数m, value%m的值一样的节点算一类, 请把所有的类根据单链表的方式重新连接好,返回每一类的 ...

  2. structed streaming 触发器trigger

    structed streaming的执行批次,较spark streaming有所改变.更加灵活.总结下来,可大白话地分为三类: 1尽可能快的执行,不定时间 2按固定间隔时间执行 3仅执行一次 详情 ...

  3. Java 网络编程 —— 创建非阻塞的 HTTP 服务器

    HTTP 概述 HTTP 客户程序必须先发出一个 HTTP 请求,然后才能接收到来自 HTTP 服器的响应,浏览器就是最常见的 HTTP 客户程序.HTTP 客户程序和 HTTP 服务器分别由不同的软 ...

  4. defcon-quals 2023 crackme.tscript.dso wp

    队友找到的引擎TorqueGameEngines/Torque3D (github.com) 将dso文件放到data/ExampleModule目录下,编辑ExampleModule.tscript ...

  5. karyoploteR: 基因组数据可视化 R 包

    karyoploteR,是一个适用于所有基因组数据(any data on any genome)非圆环布局(non-circular layouts)的可视化 R/Bioconductor 包.开发 ...

  6. K8S | 核心原理分析

    目录 一.背景 二.持续集成 三.K8S架构 1.核心组件 2.分层结构 3.核心能力 3.1 发现与负载 3.2 调度 3.3 自动伸缩 四.应用案例 1.服务部署 2.交互流程 五.参考源码 整体 ...

  7. CANoe工具的安装

    CANoe是德国Vector公司为汽车总线的开发而设计的一款总线开发环境,全称叫CAN open environment,用于分析和模拟CAN(Controller Area Network)和LIN ...

  8. [ARM汇编]计算机原理与数制基础—1.1.1计算机的基本原理

    计算机是一种能够根据指令集自动.高速处理数据的现代化设备.它的基本原理可以总结为:输入.存储.处理和输出数据.接下来,我们将详细介绍这些基本原理. 输入 计算机通过输入设备(如键盘.鼠标等)接收外部数 ...

  9. .NET7 中Autofac依赖注入整合多层,项目中可直接用

    一.配置Autofac替换内置DI 1.安装Nuget包:Autofac.Extensions.DependencyInjection 2.Program.cs中加上 builder.Host.Use ...

  10. 2021/1/10例会 academy of management journal 2014vol 57 No.2,484-514

    这次的论文由于考试周的原因看的不是很细,但大概还是浏览过一遍了.然后这次我的拓展又神奇的匹配到了教授想让我们接下来想看的论文. perfect! 但不足的是,没有进行相关论文的检索,自己的拓展没有理论 ...