Example
Given a list comprehension you can append one or more if conditions to filter values.
[ for in if ]For each in ; if evaluates to True, add [usually a function of ] to the returned list.
For example, this can be used to extract only even numbers from a sequence of integers:
[x for x in range[10] if x % 2 == 0] # Out: [0, 2, 4, 6, 8]Live demo
The above code is equivalent to:
even_numbers = [] for x in range[10]: if x % 2 == 0: even_numbers.append[x] print[even_numbers] # Out: [0, 2, 4, 6, 8]Also, a conditional list comprehension of the form [e for x in y if c] [where e and c are expressions in terms of x] is equivalent to list[filter[lambda x: c, map[lambda x: e, y]]].
Despite providing the same result, pay attention to the fact that the former example is almost 2x faster than the latter one. For those who are curious, this is a nice explanation of the reason why.
Note that this is quite different from the ... if ... else ... conditional expression [sometimes known as a ternary expression] that you can use for the part of the list comprehension. Consider the following example:
[x if x % 2 == 0 else None for x in range[10]] # Out: [0, None, 2, None, 4, None, 6, None, 8, None]Live demo
Here the conditional expression isn't a filter, but rather an operator determining the value to be used for the list items:
if elseThis becomes more obvious if you combine it with other operators:
[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]Live demo
If you are using Python 2.7, xrange may be better than range for several reasons as described in the xrange documentation.
[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]The above code is equivalent to:
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]One can combine ternary expressions and if conditions. The ternary operator works on the filtered result:
[x if x > 2 else '*' for x in range[10] if x % 2 == 0] # Out: ['*', '*', 4, 6, 8]The same couldn't have been achieved just by ternary operator only:
[x if [x > 2 and x % 2 == 0] else '*' for x in range[10]] # Out:['*', '*', '*', '*', 4, '*', 6, '*', 8, '*']See also: Filters, which often provide a sufficient alternative to conditional list comprehensions.