Is there something similar to ?: operator (C/C++) in Python?

D

D H

Riccardo said:
That's not true.
One used form is this:
result = cond and value1 or value2

So anywhere someone uses x?y:z you recommend they use "x and y or z"
instead, or else "[y,z][x]", but not:

if x:
val = y
else:
val = z

I still would recommend just using an if statement, even though it is
not easier to type than a ternary expression. It is the most readable
and understandable equivalent in Python. And since his question was
about an easier way to do it in Python, and I don't believe your
alternative are any easier either, I believe the answer is still no.
 
S

Steven D'Aprano

Riccardo said:
That's not true.
One used form is this:
result = cond and value1 or value2

So anywhere someone uses x?y:z you recommend they use "x and y or z"
instead, or else "[y,z][x]", but not:

if x:
val = y
else:
val = z

That's not what he said at all. Nowhere did Riccardo suggest that one or
the other method was better than if..else. The *most* he did was to
suggest a personal opinion that cond and value1 or value2 was "nice".

I still would recommend just using an if statement, even though it is
not easier to type than a ternary expression.

That's fine. Recommend it all you like. But it isn't the only way, and it
isn't even arguably the best or easiest or simplest way.
It is the most readable
and understandable equivalent in Python.

To you maybe. Actually, to me also. But "easier" doesn't just mean
"easier to read" -- it also means "easier to write", "easier to
maintain", "easier to insert in one-liners", "easier to put in lambda
functions", and maybe even "easier to delete when I no longer need it".

For at least some of these requirements, the if..else solution is the
worst, not the best, solution.

And since his question was
about an easier way to do it in Python, and I don't believe your
alternative are any easier either, I believe the answer is still no.

There's an easy way to settle this once and for all. If somebody can come
up with a good empirical test for "easier" (easier what?), we can run
some tests, get some hard figures for, eg, how many calories are expended
in typing one form over the other, and find out which is easier.

Until then, the question is at least partly a matter of personal taste,
and as such, there is no justification for such sweeping generalities as
"the answer is simply no, just use an if statement instead".
 
D

D H

Steven said:
Riccardo said:
On Fri, 24 Jun 2005 09:00:04 -0500, D H wrote:



Bo Peng wrote:



I need to pass a bunch of parameters conditionally. In C/C++, I can
do func(cond1?a:b,cond2?c:d,.....)

Is there an easier way to do this in Python?


The answer is simply no, just use an if statement instead.


That's not true.
One used form is this:
result = cond and value1 or value2

So anywhere someone uses x?y:z you recommend they use "x and y or z"
instead, or else "[y,z][x]", but not:

if x:
val = y
else:
val = z


That's not what he said at all. Nowhere did Riccardo suggest that one or
the other method was better than if..else. The *most* he did was to
suggest a personal opinion that cond and value1 or value2 was "nice".

He said "that's not true", when I suggested that there is not something
easier than ? ternary expressions in Python, and that the original
poster should use if statements instead. So yes, that is what he said
by refuting my suggestion. He must have misinterpreted my response as
"if statements are the only way to do something like ternary
expression", which is not what I said. Again, I said there is *nothing*
that is as easy as to use as ternary expressions in Python - use if
statements instead.

That's fine. Recommend it all you like. But it isn't the only way, and it
isn't even arguably the best or easiest or simplest way.

You have assumed the same mistaken interpretation of my remarks as he
did. When did I ever say an if statement is the *only* way? In the
very note to which you responded, I even acknowledged two other ways of
doing this. If statements are in the best and easiest and simplest way
to do conditionals, however, which is exactly what I was arguing.

To you maybe. Actually, to me also. But "easier" doesn't just mean
"easier to read" -- it also means "easier to write",

I explicitly stated in the very note you replied to that if statements
are easier to understand and read, yet not easier to write than ?
ternary conditionals. So thanks for duplicating my own point.

Until then, the question is at least partly a matter of personal taste,
and as such, there is no justification for such sweeping generalities as
"the answer is simply no, just use an if statement instead".

Except that is the right answer. It's too bad diehard Python
evangelists (to borrow another one of Peter Hansen's flames) don't give
people straight answers when they are looking for a feature that python
just doesn't have and likely will never have, such as the ? ternary
operator. The answer is no, there is nothing as easy to use as that in
Python, and I suggested using if statements instead.
 
M

Mike Meyer

Riccardo Galli said:
The answer is simply no, just use an if statement instead.

That's not true.
One used form is this:
result = cond and value1 or value2

which is equal to
if cond:
result=value1
else:
result=value2


another form is:

result = [value2,value1][cond]


the first form is nice but value1 must _always_ have a true value (so not
None,0,'' and so on), but often you can handle this.

Note that [value2, value1][cond] doesn't do exactly what cond ? value1 : value2
does either. The array subscript will always evaluate both value2 and
value1. The ?: form will always evaluate only one of them. So for
something like:

[compute_1000_digits_of_pi(), compute_1000_digits_of_e][cond]

you'd really rather have:

cond ? compute_1000_digits_of_e() : compute_1000_digits_of_pi()

There are other such hacks, with other gotchas.

<mike
 
R

Ron Adam

Mike said:
Bo Peng wrote:


I need to pass a bunch of parameters conditionally. In C/C++, I can
do func(cond1?a:b,cond2?c:d,.....)

Is there an easier way to do this in Python?


The answer is simply no, just use an if statement instead.

That's not true.
One used form is this:
result = cond and value1 or value2

which is equal to
if cond:
result=value1
else:
result=value2


another form is:

result = [value2,value1][cond]


the first form is nice but value1 must _always_ have a true value (so not
None,0,'' and so on), but often you can handle this.


Note that [value2, value1][cond] doesn't do exactly what cond ? value1 : value2
does either. The array subscript will always evaluate both value2 and
value1. The ?: form will always evaluate only one of them. So for
something like:

[compute_1000_digits_of_pi(), compute_1000_digits_of_e][cond]

you'd really rather have:

cond ? compute_1000_digits_of_e() : compute_1000_digits_of_pi()

There are other such hacks, with other gotchas.

<mike

If you use function like you suggest, then this will work.

result = [compute_1000_digits_of_pi, compute_1000_digits_of_e][cond]()

Note the trailing ()'s which will call one or the other function after
the condition is evaluated but not both.

Regards,
Ron
 
A

Andrew Durdin

result = [(lambda: expr0), lambda: expr1][cond]()

Which still has an error, as evidenced by the following:
cond = ""
result = [(lambda: expr0), lambda: expr1][cond]()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: list indices must be integers

Corrected version:

result = [(lambda: expr0), lambda: expr1][bool(cond)]()

Or if using python < 2.3:

result = [(lambda: expr0), lambda:
expr1][__import__("operator").truth(cond)]()

Andrew
 
R

Roy Smith

Andrew Durdin said:
Corrected version:

result = [(lambda: expr0), lambda: expr1][bool(cond)]()

I'd go one step further. Most people expect the first item to correspond
to True and the second one to correspond to False. So:

result = [(lambda: expr0), lambda: expr1][bool(not cond)]()

or perhaps even better:

result = [(lambda: expr0), lambda: expr1][1 - bool(cond)]()

or, if you prefer a slightly more deranged version:

result = [(lambda: expr0), lambda: expr1][bool(cond) - 1]()
 
S

Scott David Daniels

Roy said:
Andrew Durdin said:
Corrected version:
result = [(lambda: expr0), lambda: expr1][bool(cond)]()
Sorry, I thought cond was a standard boolean.
Better is:
result = [(lambda: true_expr), lambda: false_expr][not cond]()

--Scott David Daniels
(e-mail address removed)
 
A

Antoon Pardon

Op 2005-06-29 said:
Roy said:
Andrew Durdin said:
Corrected version:
result = [(lambda: expr0), lambda: expr1][bool(cond)]()
Sorry, I thought cond was a standard boolean.
Better is:
result = [(lambda: true_expr), lambda: false_expr][not cond]()

How about the following:

result = (cond and (lambda: true_expr) or (lambda: false_expr))()
 
R

Ron Adam

Antoon said:
Op 2005-06-29 said:
Roy said:
Corrected version:
result = [(lambda: expr0), lambda: expr1][bool(cond)]()

Sorry, I thought cond was a standard boolean.
Better is:
result = [(lambda: true_expr), lambda: false_expr][not cond]()


How about the following:

result = (cond and (lambda: true_expr) or (lambda: false_expr))()

That works as long as long as they are expressions, but the ? format
does seem to be more concise I admit.


To use *any* expressions in a similar way we need to use eval which is a
lot slower unfortunately.

result = eval(['expr0','expr1'][cond])


A thought occurs to me that putting index's before the list might be an
interesting option for expressions.

result = expr[expr0,expr1]


This would probably conflict with way too many other things though.
Maybe this would be better?

result = index from [expr0,expr1]


Where index can be an expression. That is sort of an inline case
statement. Using a dictionary it could be:

result = condition from {True:expr1, False:expr0}


As a case using values as an index:

case expr from [
expr0,
expr2,
expr3 ]


Or using strings with a dictionary...

case expr from {
'a':expr0,
'b':expr1,
'c':expr3 }
else:
expr4

Reads nice, but can't put expressions in a dictionary or list without
them being evaluated first, and the [] and {} look like block brackets
which might raise a few complaints.

Can't help thinking of what if's. ;-)

Cheer's
Ron
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top