Reputation: 446
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
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]
i=5
, i != 10
in the "first expression", so you move to else
; where i < 7
so you get i-5
, or 0
i=10
, i == 10
so you get i**2
, or 100
i=15
, i != 10
so you move to else
, where i
is not less than 7
, so you get i+5
, or 20
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
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
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