程序员求职经验分享与学习资料整理平台

网站首页 > 文章精选 正文

Python 列表生成式全解

balukai 2025-01-16 17:56:12 文章精选 8 ℃

Python 中的列表生成式(List Comprehensions)是一项内置且功能强大的特性,虽然使用起来简单,但却能极大地简化创建列表的过程。

一、基础用法示例及优势对比

(一)常规创建列表的方式

通常,要生成一个像 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 这样的列表,我们可以借助 list 函数和 range 函数来实现,示例如下:

print(list(range(1, 11)))

运行结果就是我们期望的 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]。

然而,要是想生成更复杂一点的列表,比如 [1 * 1, 2 * 2, 3 * 3,..., 10 * 10],一种常见的做法是使用循环,代码如下:

L = []
for x in range(1, 11):
    L.append(x * x)
print(L)

这样最终得到的 L 就是 [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]。但不难发现,使用循环的方式来创建列表,代码显得比较繁琐,尤其当列表生成逻辑更为复杂时,代码行数会更多,阅读和维护起来也相对麻烦。

(二)列表生成式的便捷之处

这时,列表生成式就能展现出它的优势了,同样是生成 [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] 这个列表,使用列表生成式仅需一行简洁的语句就能搞定:

print([x * x for x in range(1, 11)])

其语法结构就是把要生成的元素表达式(这里是 x * x)放在前面,后面跟上 for 循环(用于遍历可迭代对象,此处是 range(1, 11)),这样 Python 就能按照这个规则快速创建出我们想要的列表了。多练习几次这种写法,就能很快熟悉并掌握列表生成式的基本语法啦。

二、添加条件筛选的用法

在列表生成式中,for 循环后面还可以添加 if 判断语句,通过这种方式,我们能够对可迭代对象中的元素进行筛选,只将满足条件的元素用来生成列表。

例如,要筛选出 1 到 10 中所有偶数的平方来生成列表,可以这样写:

print([x * x for x in range(1, 11) if x % 2 == 0])

运行后得到的结果就是 [4, 16, 36, 64, 100],这里的 if x % 2 == 0 条件判断起到了筛选作用,只有 x 为偶数时,对应的 x * x 才会被添加到最终生成的列表中。

三、多层循环的用法

列表生成式还支持多层循环,利用这一特性可以生成一些更复杂的列表元素组合,比如生成全排列的情况。

以两个循环为例,假如要生成由两个字符串中元素两两组合而成的列表,可以这样写:

print([m + n for m in 'ABC' for n in 'XYZ'])

其执行逻辑是,外层循环遍历 'ABC' 中的每个字符,对于外层循环每次取到的字符 m,内层循环都会遍历一遍 'XYZ' 中的每个字符 n,然后将 m 和 n 拼接起来作为新元素添加到列表中,最终生成的列表为 ['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']。


不过,一般来说,三层及三层以上的循环在实际应用中很少用到,因为随着循环层数的增加,代码的复杂度会迅速上升,可读性也会变差。

四、实际应用示例

(一)列出当前目录下的文件和目录名

运用列表生成式,我们可以写出非常简洁的代码来实现一些实际功能,比如列出当前目录下的所有文件和目录名,借助 Python 的 os 模块(这里先简单使用,模块的详细概念后续会讲到),通过以下一行代码就能实现:

import os
print([d for d in os.listdir('.')])

执行这段代码,就能得到当前目录下所有文件和目录名组成的列表啦(具体结果会根据实际目录内容而定)。

(二)结合字典生成特定格式的列表

在 Python 中,for 循环其实可以同时使用两个甚至多个变量,像字典的 items() 方法就能同时迭代键和值,示例如下:

d = {'x': 'A', 'y': 'B', 'z': 'C'}
for k, v in d.items():
    print(k, '=', v)

运行后会依次输出字典中每个键值对对应的 k = v 的形式,即 y = B、x = A、z = C。

基于这种特性,列表生成式同样可以使用两个变量来生成列表,还是以上面的字典为例,我们可以这样生成一个特定格式的列表:

d = {'x': 'A', 'y': 'B', 'z': 'C'}
print([k + '=' + v for k, v in d.items()])

最终得到的列表就是 ['y=B', 'x=A', 'z=C'],这样可以方便地将字典中的键值对按照我们期望的格式整合到一个列表中。

(三)对列表中的字符串进行统一处理

再比如,有一个包含多个字符串的列表,要把列表中所有字符串都变成小写形式,使用列表生成式也能轻松实现,代码如下:

L = ['Hello', 'World', 'IBM', 'Apple']
print([s.lower() for s in L])

运行后得到的列表就是 ['hello', 'world', 'ibm', 'apple'],通过简单的表达式结合 for 循环,快速完成了对列表中所有字符串元素的统一处理。

五、if...else在列表生成式中的正确用法

在使用列表生成式时,很多人容易对 if...else 的用法产生混淆,下面我们详细讲讲它们在不同位置的正确使用规则。

(一)for后面的 if

在列表生成式中,跟在 for 后面的 if 语句是作为一个筛选条件存在的,它的作用是从可迭代对象中筛选出满足条件的元素来生成列表,所以这个 if 是不能带 else 的,要是带上 else,就不符合其作为筛选条件的语义了,Python 会直接报错,示例如下:

[x for x in range(1, 11) if x % 2 == 0 else 0]

执行这段代码,Python 会提示 SyntaxError: invalid syntax,就是因为这种写法不符合语法规则,导致无法正确解析。

(二)for前面的 if...else

而对于位于 for 前面的部分,它其实是一个表达式,这个表达式必须要能根据遍历到的元素计算出一个确定的结果,然后将这个结果作为列表元素添加进去。所以,如果只写 if 而没有 else,像下面这样的写法就是错误的:

[x if x % 2 == 0 for x in range(1, 11)]

同样,Python 会提示 SyntaxError: invalid syntax,因为 x if x % 2 == 0 这个表达式没办法根据 x 计算出一个完整的结果,缺少了 else 分支来处理不满足条件的情况。

正确的写法应该是像这样加上 else,使其成为一个完整的表达式,能够根据 x 的值计算出确定的结果:

[x if x % 2 == 0 else -x for x in range(1, 11)]

这样,列表生成式就能按照规则,根据 x 是否为偶数,返回 x 或者 -x 作为列表元素,最终生成的列表就是 [-1, 2, -3, 4, -5, 6, -7, 8, -9, 10]。

综上所述,在一个列表生成式中,for 前面的 if...else 是用于构成一个能根据元素计算出确定结果的表达式,而 for 后面的 if 则是单纯的过滤条件,二者有着不同的作用和语法要求,一定要正确区分使用哦。

最近发表
标签列表