Python 学习笔记 #5 —— Comprehension 解析式
Posted on 2020-05-16 20:58 in CS
What is List Comprehensions
PEP 202 -- List Comprehensions 原文链接。
List Comprehensions 是一种 python 语法扩展,它可以实现用 for 和 if 语句直接构建 list。
Examples
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
Why Comprehensions
如果想用从一个 list 中挑选出一部分满足条件的元素组成一个新的 list,该怎么做?
- 方法一:最直观简单的方法,写一个
for
循环,然后从中挨个挑选出符合条件的元素 - 方法二:使用函数式编程中的
map()
/filter()
既然方法一和方法二都能实现相同的功能,为什么还需要再提出 list comprehensions 呢?
答案是:为了更加优雅的构建 list。
方法一虽然简单但是很臃肿,方法二要调用两个函数(map
/filter
, lambda
)仍然不够简化,所以出现了 list comprehensions
, 它实际上来自于函数式编程语言 Haskell,提供了另外一种更加简洁的实现方法(Simple is better than complex.)。
Understanding and Using List Comprehensions
以数学的角度理解 list comprehensions
下面这个集合表示从自然数中挑选出符合条件 x > 5
且 x < 10
的所有元素,
下面是 Python 的实现版本,
1 |
|
对比一下 python 版本的代码就可以知道两者非常相似,只不过 python 用 for 和 if 语句来描述数学中的条件表达式。尤其是 python 中有集合 set
的概念,set 也是可以写成 comprehensions 形式的,这个时候就和数学就完全等价了。
如何写 list comprehensions
因为 list comprehensions 本质是 for 和 if 的简洁写法,所以我们可以总结出一个模板,只要满足这个模板的 for 循环就可以改成写 list comprehensions.
1 2 3 |
|
可以改写成下面的形式
1 |
|
循环嵌套的 list comprehensions
循环嵌套的 list comprehensions 例子:将矩阵展平,
1 2 3 |
|
可以写成
1 |
|
提高 list comprehensions 的可读性
因为 python 支持在括号之间断行,所以前面的例子,可以改写成下面的形式以提高可读性:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
小结
无论是单层还是嵌套的 for 循环,改成 list comprehensions 的方法其实方法非常简单,就是把普通的 for 循环调整了顺序,将循环内的语句写在了最前面,剩余部分按原顺序写就可以了。
- 上面的语法只适用于一个元素(the Right One)
- 不允许写成
[x, y for ...]
形式,但是可以写成一个 tuple 元素的形式[(x, y) for ...]
- 允许嵌套形式
[... for x... for y...]
,就像嵌套循环一样,最后一个 index 是变化最快的
GvR 也说 map()
/ filter()
函数用起来实在太繁琐了,我们应该多使用 comprehensions。但是我们应该记住,谨防滥用。
filter and map should die and be subsumed into list comprehensions, not grow more variants. I'd rather introduce built-ins that do iterator algebra (e.g. the iterzip that I've often used as an example).
(关于 iterator
,后面的学习笔记中会有介绍。)
Dict Comprehensions
PEP 274 -- Dict Comprehensions 原文链接。
dict comprehensions 和 list comprehensions 非常相似,不同之处就是采用 dict
的相关语法:用 {}
而不是 []
,同时关键字 for
前面的部分表达式改成了用冒号隔开的 key-value 对。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
Set Comprehensions
set comprehensions 和 list comprehensions 非常相似,唯一的区别就是用 {}
而不是 []
。
1 2 |
|
显然因为最终生成的是集合,所以重复元素只会保存一个。
Ref
This post is part 6 of the "Python Notes" series:
- Python 学习笔记 #0 —— 新的开始
- Python 学习笔记 #1 —— PEP8 编程风格
- Python 学习笔记 #2 —— PEP8 实践
- Python 学习笔记 #3 —— Docstring 风格
- Python 学习笔记 #4 —— Python 之禅
- Python 学习笔记 #5 —— Comprehension 解析式
- Python 学习笔记 #6 —— Iterator 迭代器
- Python 学习笔记 #7 —— Generator 生成器
- Python 学习笔记 #8 —— Decorator 装饰器
- Python 学习笔记 #9 —— Function Arguments 函数参数
- Python 学习笔记 #10 —— Python 中的 FP