Here's what you want
("x is greater than y", "x is less than y", "x is equal to y")[(x < y) or (x==y)*2]
Looks weird, ha?
That's because in the square brackets after a tuple python expects a number.
And the thing is, conditional false
evaluates to 0
and conditional true
evaluates to 1
with implicit type coercion.
So to make this work you would have to figure out a oneliner with conditionals, that will evaluate as follows:
0
if x > y
1
if x < y
2
if x == y
We can utilize a so-called short-circuiting properties (see: https://stackoverflow.com/a/14892812).
- this guy
x < y
makes for the first 2 cases. We can separate it out with parenthesis: (x < y)
.
- with
(x < y) or whatever
, it will produce true
(1
) with the first statement if x < y
and stop there, but if x < y
happens to be false
(0
), then the or
statement will proceed on evaluating the statement on the right, and return whatever
, whatever it will be.
- so with
(x < y) or (x==y)*2
, if x < y
then it will return true
(1
) right away, but if not: it will return (x==y)*2
, which is either false
(0
) or true
(1
) multiplied by 2
, so either 0
or 2
.
Thus we have:
0
, if both x < y
and x == y
are false (i.e. x > y
)
1
, if x < y
returns true
(1
)
2
, if x < y
is false
, and x==y
is true
(1
)
In fact, if we utilize short-circuiting properties of and
statement, (x==y)*2
may be substituted to (x==y) and 2
, yielding the same results, but running with a bit less CPU time. This approach may be used to refactor numbers of nested if
statements that is intended to run a big number of times (usually > 1'000'000 times), and is called branchless programming.
P.S. You may want not to put everything in one line.