Elif' in List Comprehension Conditionals

`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 into

v = 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 number

y = [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



Leave a reply



Submit