This question already has an answer here:
I have the following list comprehension.
return [tower for tower in state if tower != space else []]
But when I run it, python spits back this error:
return [tower for tower in state if tower != space else []]
^
SyntaxError: invalid syntax
If I remove the else statement, it runs fine. Am I writing the else statement wrong somehow?
That's because python doesn't support
if-else
in list comprehension filters, onlyif
clauses.You can however achieve the result you want by using a conditional expression
List comprehensions support
if
but notelse
because theif
section filters elements, you either include an element or you don't include it, a boolean choice.If you wanted to use a conditional expression to build the iterable part of the
for
loop, use parentheses:but I suspect that you wanted to alter the value of the expression in the element expression instead; that's not filtering, you are simply producing a different value for certain items. Use a conditional expression to produce your values:
or if you really wanted to filter, simply omit the
else
:When constructing a list comprehension, remember that you need to read the expression as nested from left to right, with the final expression producing the result out on the left:
is the moral equivalent of:
where you can use as many nested loops and
if
filters as your use case requires.The three options I described above are then the same as:
How about this:
You are putting the else in the
for
clause of the comprehension, but you need to put the entire if/else expression in the target expression:When you use
for tower in state if <condition>
you are saying you want to not even make use of items instate
if they don't satisfy the condition. In this case, you can't use anelse
, because all you can do is either process each item (including something in the list comprehension result), or not.The
X if Y else Z
, on the other hand, is a normal expression that can be used as the target expression of the list comprehension. This means that every element in the source iterable will generate an element in the result, but the if/else determines what that result item will be.