Home > Net >  Multiple if/else on list comprehensions
Multiple if/else on list comprehensions

Time:09-22

I am trying to learn list comprehensions Conditionals on iterable. My problem is, I don't understand how my if/else condition working on this list. which if or else working first and printing.

num1 = [5, 10, 15]
num2 = [i**2 if i == 10 else i - 5 if i < 7 else i   5 for i in num1]
print(num2)

Output:

[0, 100, 20]

CodePudding user response:

What you have here is not a list comprehension with conditionals (which filters out some elements of the comprehension), but a post-expression conditional of the form

x = A if (condition) else B

This assigns A if (condition) is true, otherwise it assigns B. (The syntax is a little confusing to look at, it must be admitted, but even Python is not always perfect.) You've managed to stack two of these inside each other, like this:

i**2 if i == 10 else (i-5 if i < 7 else i 5)

Reading from the right: The expression (i-5 if i < 7 else i 5) will give you i-5 if i<7, else you get i 5. Whatever value this is, it is included in the comprehension whenever i==10 is false (so, for the first and third list element).

Note that this construction has nothing to do with a list comprehension; you can use it anywhere (as long as i is defined).

i = 31
x = i**2 if i == 10 else (i-5 if i < 7 else i 5)

For comparison, here is a real conditional list comprehension: The comprehension will remove values that are equal to 10, leaving you with two elements in the result. I think this is the construction you set out to understand.

num3 = [ i**2 for i in num1 if i != 10 ]

CodePudding user response:

To actually understand how that nested ternary is working, you can write the equivalent branching statement:

num2 = []
for i in num1:
    val = i
    if i == 10:
        val **= 2
    elif i < 7:
        val -= 5
    else:
        val  = 5
    num2.append(val)

Note that no matter what i is, val is always assigned a value. This is a requirement for ternary expressions.

In general a ternary expression follows the form

x = expr_if_true if some_condition else expr_if_false

Which is equivalent to

if some_condition:
    x = expr_if_true
else:
    x = expr_if_false

Notice that expr_if_true and expr_if_false can be any valid Python expression, including other ternary expressions. This is the mechanism by which ternary expressions can nest, and this works specifically because ternary expressions always have a return value.

All that said, it's a terrible way to write code. Ternary expressions should be limited to a single level, MAYBE one level of nesting if it can be written concisely and read easily.

  • Related