Daniel Kim
Daniel Kim

Reputation: 446

One liner with nested if/else conditions

Real python noob here, and I'm a bit puzzled by looking at the result of this nested if/else one-liner:

>>> num_arr = [5, 10, 15]
>>> [i**2 if i == 10 else i-5 if i < 7 else i+5 for i in num_arr]
[0, 100, 20]

Shouldn't the result be [0, 15, 20] since 10 is greater than 7?

Upvotes: 2

Views: 244

Answers (3)

Zach Gates
Zach Gates

Reputation: 4130

As I mentioned in the comments, the "correct" version (note the parentheses) is:

[(i**2 if i == 10 else i-5) if i < 7 else i+5 for i in num_arr]

Your "problem" stems from the chaining of your if statements, which execute in the English reading order (left to right). So it reads like this:

[i**2 if i == 10 else (i-5 if i < 7 else i+5) for i in num_arr]
  • where i=5, i != 10 in the "first expression", so you move to else; where i < 7 so you get i-5, or 0
  • where i=10, i == 10 so you get i**2, or 100
  • where i=15, i != 10 so you move to else, where i is not less than 7, so you get i+5, or 20

From the documentation:

To make the semantics very clear, a list comprehension is equivalent to the following Python code:

for expr1 in sequence1:
    for expr2 in sequence2:
    ...
        for exprN in sequenceN:
             if (condition):
                  # Append the value of
                  # the expression to the
                  # resulting list.

That means yours looks like:

[[expr1] if [condition] else [[expr2] if [condition] else [expr3]] for ...]

Upvotes: 4

Dave
Dave

Reputation: 53

Here's the expanded version of the one liner:

for i in num_arr:
    if i == 10:
        i ** 2
    else:
        if i < 7:
            i - 5
        else:
            i + 5

The one-liner if statement is basically: [action] if [condition] else [action]. In other words, do this if said condition is met. Otherwise, do this action.

It's a reason I don't like one-liners is because they become less Pythonic. The code above is more verbose but it's easier to understand.

Upvotes: 1

Eric Truett
Eric Truett

Reputation: 3010

The value if the condition is True is stated before the if and the value if False is after the else (see https://docs.python.org/2.5/whatsnew/pep-308.html).

Result is i-5 for 5 because i is not 10 but it is < 7

Result is i ** 2 for 10 because i == 10

Result is i + 5 for 15 because i is not 10 and it is not < 7

Hence [0, 100, 20]

Upvotes: 0

Related Questions