条件清单理解

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

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

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

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

[x for x in range(10) if x % 2 == 0]
# Out: [0, 2, 4, 6, 8]

现场演示

以上代码相当于:

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

print(even_numbers)
# Out: [0, 2, 4, 6, 8]

此外,形式 [e for x in y if c] 的条件列表理解(其中 ecx 的表达式)等同于 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)]
# Out: [0, None, 2, None, 4, None, 6, None, 8, None]

现场演示

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

<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)]
# Out: [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)]
# Out: [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)
# Out: [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]
# Out: ['*', '*', 4, 6, 8]

只有三元运算符才能实现同样的目标:

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

另请参阅: 过滤器 ,它通常为条件列表推导提供了足够的替代方法。