1

I'm trying see how I can use a tuple in conditional statement like this:

(False_condition, True_Condition)[conditional expression]

Assign example values:

x, y = 4, 7

Conditional:

("x is greater than y", "x is less than y") [x < y]

Output:

'x is less than y'

Problem: What if x == y?

Assign value:

x,y = 5,5

Conditional:

("x is greater than y", "x is less than y", "x is equal to y") [x < y]

Output:

"x is greater than y"

Question: In this method, can you NOT have a third option?

4 Answers 4

2

You can get to what you want with this:

print(( "x is less than y", "x is equal to y", "x is greater than y")[ [x<y,x==y,x>y].index(True)])
Sign up to request clarification or add additional context in comments.

3 Comments

Could you please explain how this works? What's happening?
I put all three conditions in a list. Only one of them will be true and the index method reports the index of that one, which is then used to pick the text string from the tuple of the descriptions.
this is actually the best solution. You can list any number of conditions this way, they all will be in the order, and it looks intuitive.
2

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).

  1. this guy x < y makes for the first 2 cases. We can separate it out with parenthesis: (x < y).
  2. 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.
  3. 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.

1 Comment

This is a thorough explanation that helps me understand some fundamental concepts. thanks.
0

You can use lambdas they are more efficient because in lambda only one expression will be evaluated unlike in tuple and Dictionary :

(lambda x,y:"x:{} is greater than y:{}".format(x,y), lambda x,y: "x:{} is less than y:{}".format(x,y) if x<y else "x:{} equal to y:{}".format(x,y))[x<=y](x,y)

enter image description here

Comments

0

What I usually use:

>>> for x, y in (1, 2), (2, 2), (2, 1):
        print('=<>'[(x < y) - (x > y)])

<
=
>

Although kukuster is right, or is faster. I might switch.

>>> for x, y in (1, 2), (2, 2), (2, 1):
        print('=<>'[(x < y) or -(x > y)])

<
=
>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.