在 python 中存在一种很奇妙的「列表推导式」语法,例如以下的例子:
res_list = [s.strip() for s in xcol_values.split(',') if s != 'body']
对于这种语法有时候真的很难理解,如何「快速理解」这个语法结构的含义呢?
语法结构
列表推导式的存在意义是定义「从原始数据中筛选并加工数据,生成一个新容器承接数据」的流程。
首先我们先来看看这种语法的基本结构,为后面的快速理解打打基础。
result = [表达式 for 变量 in 可迭代对象 [if 条件]]
他的结构主要是三部分:
- 表达式
- for 变量 in 可迭代对象
- if 条件(被 [] 括起来代表语句可选,可写可写)
- 最外层括起来的 []
这种结构对应的实际代码是:
result = []
for 变量 in 可迭代对象:
if 条件:
result.append(表达式)
是不是这段实际代码比较好理解,逻辑也清晰一点,没错!列表推导式实际上就是这段代码的简化写法,最终的目的就是实现对这段代码的书写简化,让代码更加简洁专注于业务操作,减少冗余的逻辑代码,说的更精练一些就是一种语法糖。
快速理解
快速理解分为四步:
第一步:确定数据源
以刚刚上面的代码作为例子:
res_list = [s.strip() for s in xcol_values.split(',') if s != 'body']
在代码中 for 变量 in 可迭代对象 的结构就是数据源(看到 for 和 in 就整块圈出来理解),我们需要先确认数据是从什么地方读取出来的,可以看到 xcol_values.split(',') 代表字符串 xcol_values 使用 , 分割后的字符串数组;
那么 for s in xcol_values.split(',') 就是代表从字符串 xcol_values 使用 , 分割后的字符串数组中遍历每一个字符串元素,每次遍历时的字符串元素使用 s 变量存储。
这个时候我们就确定数据源,也就是要处理的是那一些数据,后续准备筛选和加工的的就是这些数据啦。
第二步:确认筛选条件
在 for 变量 in 可迭代对象 后面跟着的 if 开头的 if 条件 就是定义的筛选条件,他表示对数据源中的每一个遍历读取的元素,在这里也就是 s进行 if 条件 语句的判断,如果是 true 则代表 s 变量中的元素可以留下,否则是 false 代表这个元素必须丢弃。
例子中的 if s != 'body' 表示对字符串数组中的每一个字符串元素 s,如果字符串不是 'body' 就可以留下,是 'body' 就丢弃不要,实际作用就是筛选出数据源中不是 'body' 的字符串元素留下。
这个筛选条件是可选的,也就是 for 变量 in 可迭代对象 后面可以不跟 if 条件,表示从数据源中读取的元素不进行任何的筛选操作。
第三步:确认加工流程
经过前两步的「数据源」和「筛选」数据已经是初见端倪了,这时候是可以直接使用容器装了吗,其实在装入容器前还可以再进行一下加工,也就是位于列表推导式最开始的语句 表达式 所定义的操作。
s.strip() 代表对筛选后留下的字符串元素,去掉其周围空格。
第四步:确认装入容器
最后经过了从什么「数据源」遍历读取出数据,然后对数据进行逐个「筛选」最后选剩下的数据逐个「加工」就可以放入生成的新容器中了,这个容器要确认一下是「列表」、「集合」还是「字典」等,因为不同的容器存储数据的特点是不一样的,例如集合是无序不重复的,列表是有序可重复的,字典是需要有 key 和 value 的,
不同的特点最后可能还会进行操作,举个例子集合就会对最后加工出来的元素在进行一次自动的去重,而列表就不会自动去重,但是会天然的保持元素从数据源出来到推导式生成元素的顺序。
[s.strip() for s in xcol_values.split(',') if s != 'body'] 是使用 [] 括起来的代表生成容器就是列表,最后所有数据都将用列表承接装入;
使用 () 括起来是元组,对应他的推导式叫做元组推导式;
使用 {} 括起来的,如果表达式生成的是单个元素,那么是集合,对应叫做集合推导式,如果表达式生成的是键值对,那么是字典,对应叫做字典推导式。
# 集合推导式
{key 表达式: value 表达式 for 变量 in 可迭代对象 [if 条件]}
# 字典推导式
{表达式 for 变量 in 可迭代对象 [if 条件]}
总结:
一个列表推导式,按照上面这四步依次拆分出每部分然后理解,那么理解代码流程的速度会快很多,理解起来也会轻松很多,有章法可循。
graph LR
START --> 1.确定数据源 --> 2.确认筛选条件 --> 3.确认加工流程 --> 4.确认装入容器 --> STOP