Python的列表解析式可以在末尾使用 if
关键字来筛选结果。但是,如果想用条件表表达式对结果进行选择,是否可行?也就是说,在列表解析式中是否可以使用 if...else...
语句。
列表解析式支持else
吗?
下面这个列表解析式是无效的:
>>> counts = [2, -1, 4, 7, -3, 6]
>>> sanitized_counts = [n for n in counts if n > 0 else 0]File "<stdin>", line 1sanitized_counts = [n for n in counts if n > 0 else 0]^^^^
SyntaxError: invalid syntax
Python 的列表解析式不支持上面那样使用else
关键字。
但是,这并不意味着不能在列表解析式中使用 else
,如果按照下面的方法编写代码,就能够正常执行了。
>>> sanitized_counts = [n if n > 0 else 0 for n in counts]
输出结果如下:
>>> sanitized_counts
[2, 0, 4, 7, 0, 6]
这是如何工作的?
Python 的三元运算符
在上面的代码中,那个else
实际上并不是解析式的一部分,if
也不是。它其实是 Python 版的三元运算符(也称为“三元操作”,更详细内容参阅第 5 章 5.2 节):
>>> n = 5
>>> n if n > 0 else 0
5
这个表达式检查条件表达式 n > 0
,如果为真,则根据表达式 n
返回结果,如果为假,则根据 else
关键字后面的表达式 0
返回结果。再如:
>>> n = -3
>>> n if n > 0 else 0
0
将这个 Python 版的三元运算符,运用到列表解析式中,就是前面看到的结果:
>>> counts = [2, -1, 4, 7, -3, 6]
>>> sanitized_counts = [n if n > 0 else 0 for n in counts]
那么,照此就可以理解,在上述列表解析式中,n if n > 0 else 0
是三元运算表达式,是一个单一的表达式,它恰好就在解析式内,不是条件表达式中的 if...else...
这样的两个分支。
使列表解析式更易读
为了避免将列表解析中的三元运算符误认为是两个条件分支,可以用下面的形式书写:
>>> sanitized_counts = [(n if n > 0 else 0) for n in counts]
避免复杂的解析式
写代码的要务之一就是可读性,为此,也可以将 n if n > 0 else 0
写到解析式的外面,将其放到一个函数里面。
>>> def negatives_to_zero(n):
... return n if n > 0 else 0
...
>>> sanitized_counts = [negatives_to_zero(n) for n in counts]
结论
由以上分析可知,Python 的列表解析式不支持 else
关键字。但是,可以通过三元运算符实现条件表达式的功能。