条件清单理解
给定列表理解, 你可以附加一个或多个 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]
的条件列表理解(其中 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)]
# 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, '*']
另请参阅: 过滤器 ,它通常为条件列表推导提供了足够的替代方法。