为什么列表理解中的if-else之前,而if则在之后?

时间:2019-07-05 15:17:53

标签: python list-comprehension

关于python可迭代理解的一般问题:

为什么这样的声明

[s for s in x if s>2]

if紧跟在for之后,但对于类似

的语句
[s if s>2 else None for s in x]

if... elsefor之前吗?

4 个答案:

答案 0 :(得分:9)

条件表达式和理解过滤器唯一的共同点是关键字 if的共享使用。

a if b else c是一个条件表达式。目的是保证b是否为真。它的使用不特定于列表理解;在[s if s > 2 else None for s in x]中,它只是用作为新列表提供值的表达式,给定s中的值x

if的另一种用法是列表理解本身语法的一部分。它不是表达式的一部分;它指定一个 filter ,该过滤器用于确定是否应将可迭代对象中的特定值传递给表达式。

如果您将列表理解视为mapfilter的组合,则该表达式代替map的函数参数,而if filter代替对filter的调用。也就是说,您可以重写任何常规列表理解

[ <expression> for s in xs if <p>]

作为mapfilter的组合,因此:

list(map(lambda s: <expression>, filter(lambda s: <p>, xs)))

您可以看到PEP-202的有关列表推导的讨论(尽管它比较老,并且没有记录可能考虑过的其他语法),而PEP-308则是关于条件表达式的 讨论了考虑的一些其他语法。

答案 1 :(得分:2)

if-else不仅限于列表理解,还可以用于赋值语句等。在列表理解中没有特殊含义。

if表达式之后的for语法选择了包含在理解中的元素,if-else无法做到,因此其用法特定于理解。

答案 2 :(得分:0)

在第一种情况下,if是所创建列表的每个元素是什么的表达式的一部分;在第二步中,它决定是否包含一个元素(因此不需要else)。

答案 3 :(得分:0)

列表理解的最一般形式是:
[expression1_of_x for x in iterable if expression2_of_x],其中expressio2_of_x是可选的。
因此,以下所有列表理解都可以接受:(expression1_of_xexpressio2_of_x
1. [s for s in x if s>2]可以。 (s,s> 2)
2. [s if s>2 else None for s in x](如果s> 2则为s,否则为None,nil)
3. [s if s>2 else None for s in x if s > 10](如果s> 2则为s,否则为s> 10)
有关更多信息,请参见the docs