`elif` in list comprehension conditionals
Python's conditional expressions were designed exactly for this sort of use-case:
>>> l = [1, 2, 3, 4, 5]
>>> ['yes' if v == 1 else 'no' if v == 2 else 'idle' for v in l]
['yes', 'no', 'idle', 'idle', 'idle']
Using if, elif and else in list comprehension in python3
elif
is not part of the if-else short-hand, aka if else conditional operator, but you can achieve the same logic by chaining these operators, for example:
if A:
v = a
elif B:
v = b
else:
v = c
turns intov = a if A else b if B else c
And you can use a conditional operator expression in your list comprehension:[a if A else b if B else c for something in someiterator]
Note that things can become unreadable quite quickly, for example this may not be recommended in your example:
['fizzbuzz' if num%3 == 0 and num%5 == 0 else 'fizz' if num%3 == 0 else 'buzz' if num%5 == 0 else num for num in range(1, 101)]
Using if, elif, else in List Comprehensions, Python
You are (ab)using conditional expressions, and they must be of the form true_expression if test else false_expression
. These expressions always produce a value, unlike an if
compound statement.
Note that you should not test for == True
; boolean expressions are already true or false without that test. Don't use <>
either, that operator has been deprecated and has removed from Python 3 altogether. When testing for None
, a singleton, you'd use is not None
however.
You are testing against type()
results; that looks like you want to use isinstance()
tests instead.
You are also using int()
on values, then calling .lower()
on the result. There is no int.lower()
method, so those calls will fail with an AttributeError
.
The following is closer to working just fine, unless there are more types than int
, float
, str
or unicode
:
[int(a[0].internal_value) if isinstance(a[0].internal_value, (float, int)) or a[0].internal_value.isdigit()
else str(a[0].internal_value).lower()
for a in ws.iter_rows() if a[0].internal_value is not None]
However, I'd farm out the conversion to filter function instead:def conversion(value):
if isinstance(value, (float, int)):
return int(value)
return str(value).lower()
then use that in a list comprehension:[conversion(a[0].internal_value) for a in ws.iter_rows() if a[0].internal_value is not None]
Single-line if-elif-else with list comprehensions
This is a great use-case for a dictionary!
First, define a dict that maps the color names to the numbers
colordict = {'yellow': 1, 'blue': 2, 'default': 3}
Then, use colordict.get()
to retrieve the correct numbery = [colordict.get(t['color'], colordict['default']) for t in item]
The second argument to .get()
is the default value that it returns if t['color']
is not found in colordict
.Using a dict makes it trivial to add more colors. Can you imagine having to write a hundred nested if-elses
to support a hundred colors?!
Testing with this dummy list:
item = [
{'color': 'yellow', 'data': 0.5},
{'color': 'purple', 'data': 0.1},
{'color': 'blue', 'data': 0.2},
{'color': 'blue', 'data': 0.3},
{'color': 'red', 'data': 0.6}
]
we get the output[1, 3, 2, 2, 3]
which is exactly what we expected.You could also use defaultdict
if you don't want to deal with .get()
.
if/else in a list comprehension
You can totally do that. It's just an ordering issue:
[f(x) if x is not None else '' for x in xs]
In general,[f(x) if condition else g(x) for x in sequence]
And, for list comprehensions with if
conditions only,[f(x) for x in sequence if condition]
Note that this actually uses a different language construct, a conditional expression, which itself is not part of the comprehension syntax, while the if
after the for…in
is part of list comprehensions and used to filter elements from the source iterable.Conditional expressions can be used in all kinds of situations where you want to choose between two expression values based on some condition. This does the same as the ternary operator
?:
that exists in other languages. For example:value = 123
print(value, 'is', 'even' if value % 2 == 0 else 'odd')
Making use of dict.get for if elif and else in List Comprehension
do you want like this?
import numpy as np
perc = np.array([0, 0.25, 0.5, 0.75, 1])
d= {0: 0, len(perc):1}
result = [d.get(x, (lambda y: ((perc[y-1]+perc[y])/2) if y < len(perc) else 99999)(x)) for x in range(len(perc)+8)]
print(result)
#[0, 0.125, 0.375, 0.625, 0.875, 1, 99999, 99999, 99999, 99999, 99999, 99999, 99999]
if else in a list comprehension
>>> xs = [22, 13, 45, 50, 98, 69, 43, 44, 1]
>>> [x+1 if x >= 45 else x+5 for x in xs]
[27, 18, 46, 51, 99, 70, 48, 49, 6]
Do-something if <condition>
, else do-something else.
Related Topics
How to Crop an Image Using Pil
Why Use Sys.Path.Append(Path) Instead of Sys.Path.Insert(1, Path)
Python Pandas Dataframe, Is It Pass-By-Value or Pass-By-Reference
Powersets in Python Using Itertools
How to Write Utf-8 in a CSV File
Python & Selenium: Difference Between Driver.Implicitly_Wait() and Time.Sleep()
Python Socket Receive - Incoming Packets Always Have a Different Size
Split Dataframe into Relatively Even Chunks According to Length
Asyncio Cancellederror and Keyboardinterrupt
Numpy Array Initialization (Fill with Identical Values)
Where Do the Python Unit Tests Go
Why Does Python Use 'Magic Methods'
How to Read a Response from Python Requests
What Is the Default _Hash_ in Python
Pandas Groupby and Sum Only One Column
How Do Threads Work in Python, and What Are Common Python-Threading Specific Pitfalls