Is it possible to use 'else' in a list comprehension? [duplicate]
Here is the code I was trying to turn into a list comprehension:
table = ''
for index in xrange(256):
if index in ords_to_keep:
table += chr(index)
else:
table += replace_with
Is there a way to add the else statement to this comprehension?
table = ''.join(chr(index) for index in xrange(15) if index in ords_to_keep)
The syntax a if b else c
is a ternary operator in Python that evaluates to a
if the condition b
is true - otherwise, it evaluates to c
. It can be used in comprehension statements:
>>> [a if a else 2 for a in [0,1,0,3]]
[2, 1, 2, 3]
So for your example,
table = ''.join(chr(index) if index in ords_to_keep else replace_with
for index in xrange(15))
If you want an else
you don't want to filter the list comprehension, you want it to iterate over every value. You can use true-value if cond else false-value
as the statement instead, and remove the filter from the end:
table = ''.join(chr(index) if index in ords_to_keep else replace_with for index in xrange(15))
To use the else
in list comprehensions in python programming you can try out the below snippet. This would resolve your problem, the snippet is tested on python 2.7 and python 3.5.
obj = ["Even" if i%2==0 else "Odd" for i in range(10)]
Yes, else
can be used in Python inside a list
comprehension with a Conditional Expression ("ternary operator"):
>>> [("A" if b=="e" else "c") for b in "comprehension"]
['c', 'c', 'c', 'c', 'c', 'A', 'c', 'A', 'c', 'c', 'c', 'c', 'c']
Here, the parentheses "()" are just to emphasize the conditional expression, they are not necessarily required (Operator precedence).
Additionaly, several expressions can be nested, resulting in more else
s and harder to read code:
>>> ["A" if b=="e" else "d" if True else "x" for b in "comprehension"]
['d', 'd', 'd', 'd', 'd', 'A', 'd', 'A', 'd', 'd', 'd', 'd', 'd']
>>>
On a related note, a comprehension can also contain its own if
condition(s) at the end:
>>> ["A" if b=="e" else "c" for b in "comprehension" if False]
[]
>>> ["A" if b=="e" else "c" for b in "comprehension" if "comprehension".index(b)%2]
['c', 'c', 'A', 'A', 'c', 'c']
Conditions? Yes, multiple if
s are possible, and actually multiple for
s, too:
>>> [i for i in range(3) for _ in range(3)]
[0, 0, 0, 1, 1, 1, 2, 2, 2]
>>> [i for i in range(3) if i for _ in range(3) if _ if True if True]
[1, 1, 2, 2]
(The single underscore _
is a valid variable name (identifier) in Python, used here just to show it's not actually used. It has a special meaning in interactive mode)
Using this for an additional conditional expression is possible, but of no real use:
>>> [i for i in range(3)]
[0, 1, 2]
>>> [i for i in range(3) if i]
[1, 2]
>>> [i for i in range(3) if (True if i else False)]
[1, 2]
Comprehensions can also be nested to create "multi-dimensional" lists ("arrays"):
>>> [[i for j in range(i)] for i in range(3)]
[[], [1], [2, 2]]
Last but not least, a comprehension is not limited to creating a list
, i.e. else
and if
can also be used the same way in a set
comprehension:
>>> {i for i in "set comprehension"}
{'o', 'p', 'm', 'n', 'c', 'r', 'i', 't', 'h', 'e', 's', ' '}
and a dictionary
comprehension:
>>> {k:v for k,v in [("key","value"), ("dict","comprehension")]}
{'key': 'value', 'dict': 'comprehension'}
The same syntax is also used for Generator Expressions:
>>> for g in ("a" if b else "c" for b in "generator"):
... print(g, end="")
...
aaaaaaaaa>>>
which can be used to create a tuple
(there is no tuple comprehension).
Further reading:
- The Python Tutorial on Data Structures
- List Comprehensions
- Sets
- Dictionaries
Great answers, but just wanted to mention a gotcha that "pass" keyword will not work in the if/else part of the list-comprehension (as posted in the examples mentioned above).
#works
list1 = [10, 20, 30, 40, 50]
newlist2 = [x if x > 30 else x**2 for x in list1 ]
print(newlist2, type(newlist2))
#but this WONT work
list1 = [10, 20, 30, 40, 50]
newlist2 = [x if x > 30 else pass for x in list1 ]
print(newlist2, type(newlist2))
This is tried and tested on python 3.4. Error is as below:
newlist2 = [x if x > 30 else pass for x in list1 ]
SyntaxError: invalid syntax
So, try to avoid pass-es in list comprehensions