Python条件列表理解

示例

给定列表理解后,您可以附加一个或多个if条件来过滤值。

[<expression> for <element> in <iterable> if <condition>]

对于每一个<element>在<iterable>; 如果<condition>计算为True,则将<expression>(通常是的函数<element>)添加到返回的列表中。


例如,可以将其用于从整数序列中仅提取偶数:

[x for x in range(10) if x % 2 == 0]
# 输出:[0、2、4、6、8]

现场演示

上面的代码等效于:

even_numbers = [] 
for x in range(10):
    if x % 2 == 0:
        even_numbers.append(x)

print(even_numbers)
# 输出:[0、2、4、6、8]

同样,形式的条件列表理解[e for x in y if c](其中e和c是用表示的表达式x)也等效于list(filter(lambda x: c, map(lambda x: e, y)))。

尽管提供了相同的结果,但请注意,前一个示例的速度几乎快于后者的2倍。对于那些好奇的人,这很好地解释了原因。


请注意,这与... if ... else ...条件表达式(有时称为三元表达式)完全不同,您可以将其用于<expression>列表理解。考虑以下示例:

[x if x % 2 == 0 else None for x in range(10)]
# 输出:[0,无,2,无,4,无,6,无,8,无]

现场演示

这里的条件表达式不是过滤器,而是运算符,用于确定要用于列表项的值:

<value-if-condition-is-true> if <condition> else <value-if-condition-is-false>

如果将其与其他运算符结合使用,这将变得更加明显:

[2 * (x if x % 2 == 0 else -1) + 1 for x in range(10)]
# 输出:[1,-1、5,-1、9,-1、13,-1、17,-1]

现场演示

如果您使用的是Python 2.7,xrange则range由于xrange文档中所述的几种原因,可能会更好。

[2 * (x if x % 2 == 0 else -1) + 1 for x in xrange(10)]
# 输出:[1,-1、5,-1、9,-1、13,-1、17,-1]

上面的代码等效于:

numbers = []
for x in range(10):
    if x % 2 == 0:
        temp = x
    else:
        temp = -1
    numbers.append(2 * temp + 1)
print(numbers)
# 输出:[1,-1、5,-1、9,-1、13,-1、17,-1]


可以结合三元表达式和if条件。三元运算符处理过滤后的结果:

[x if x > 2 else '*' for x in range(10) if x % 2 == 0]
# 输出:['*','*',4,6,8]

仅三元运算符不能实现相同的目的:

[x if (x > 2 and x % 2 == 0) else '*' for x in range(10)]
# 输出:['*','*','*','*',4,'*',6,'*',8,'*']


另请参阅:过滤器,通常可以为条件列表理解提供足够的选择。