Python:列表推导式

张开发
2026/6/10 21:01:34 15 分钟阅读
Python:列表推导式
相关阅读Python专栏https://blog.csdn.net/weixin_45791458/category_12403403.html?spm1001.2014.3001.5482列表推导式是Python中非常常用的一种语法它可以让“创建一个新列表”这件事写得更紧凑、更清晰。很多原本需要先定义空列表、再写for循环、最后不断append元素的代码都可以改写成一行列表推导式。它最常见的用途有两类一类是对可迭代对象中的每个元素做变换并把变换后的结果收集成一个新列表另一类是从可迭代对象中筛选出满足条件的元素并生成新列表。由于这种写法简洁而且表达力很强所以在日常Python代码中出现得非常频繁。先看最基础的例子比如生成平方数列表。普通写法如下squares[] for x in range(10): squares.append(x**2) print(squares) print(x) 输出 [0,1,4,9,16,25,36,49,64,81] 9这段代码的逻辑很直观先创建一个空列表然后遍历range(10)中的每一个元素把x的平方追加到列表中。这里需要注意的一点是在这种普通for循环写法中循环变量x在循环结束后仍然存在因此最后print(x)会输出9也就是最后一次迭代结束时x留下来的值。如果用函数式风格来写上面的代码还可以写成squareslist(map(lambda x:x**2,range(10)))这种写法也没有问题而且在某些场景下确实比较自然不过对于很多人来说列表推导式会更直接、更符合“从左到右读”的习惯。因此同样的逻辑通常更推荐写成squares[x**2 for x in range(10)]这就是最典型的列表推导式。它可以读成“对range(10)中的每个x计算x**2并把结果组成一个列表”。和前面的for循环相比它省掉了初始化空列表和手工append的过程因此更简洁。列表推导式的方括号内包含以下内容一个表达式后面为一个for子句然后是零个或多个for或if子句。结果是由表达式依据for或if子句求值计算而得出一个新列表。 举例来说以下列表推导式将两个列表中不相等的元素组合起来[(x, y) for x in [1,2,3] for y in [3,1,4] if x ! y] [(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]以上的复合列表推导式等价于combs [] for x in [1,2,3]: for y in [3,1,4]: if x ! y: combs.append((x, y))注意上面两段代码中for和if子句的顺序相同。表达式是元组例如上例的(x, y)或列表例如[x, y]时必须加上括号即以下语句会报错因为解释器无法判断前面的x,x**2到底应该如何和后面的for结合。正确写法应该是显式把表达式包起来。[x, x**2 for x in range(6)] #错误用法 SyntaxError: did you forget parentheses around the comprehension target? [(x, x**2) for x in range(6)] #正确用法 [[x, x**2] for x in range(6)] #正确用法除了生成一维列表列表推导式还常被用来处理嵌套列表。例如生成一个二维矩阵matrix[[ij for j in range(3)] for i in range(4)] print(matrix) 输出 [[0,1,2],[1,2,3],[2,3,4],[3,4,5]]这个例子里外层列表推导式负责生成每一行内层列表推导式负责生成行内元素。也就是说每次外层for中的i取一个值就会触发一次内层列表推导式最终形成一整行。嵌套列表推导式非常适合用来生成矩阵、网格坐标、二维初始化列表等结构但当层数太多时可读性会迅速下降因此实际使用时还是要注意不要写得过于复杂。再举一个更贴近日常数据处理的例子比如把字符串列表统一转成小写并去掉空字符串words[Hello,,World,Python,] result[w.lower() for w in words if w] print(result) 输出 [hello,world,python]这个例子很好地体现了列表推导式“先筛选再变换”的特点if w先把空字符串过滤掉然后w.lower()把剩下的字符串全部转成小写最后组成新的列表。像这种场景如果用普通循环来写往往要多写好几行而列表推导式一句就能把逻辑表达清楚。除了语法本身变量作用域也是一个很值得补充的点。原文中你用普通for循环的例子说明了x在循环结束后仍然存在这一点没有问题但如果换成列表推导式在Python3中推导式里的循环变量并不会泄露到外层作用域。例如squares[x**2 for x in range(10)] print(squares) print(x)在Python3中这里最后一行会报NameError因为列表推导式中的x只在推导式内部有效不会像普通for循环那样在外层留下来。这是列表推导式和普通for循环一个很重要的区别也是很多人第一次从for循环转向列表推导式时容易忽略的地方。

更多文章