(a==b) ? 'Yes' : 'No'

J

John Bokma

Robert Fendt said:
I never said that this would be better.

It was not my intention to imply you did. But yet I do see books on
Python mention the and or usage, and personally I think the ... if
.... else is preferable.
point of what the advantage is supposed to be of inverting the
order of the return statement and the conditional check what
should actually _be_ returned. What's wrong with just writing

if a==b:
return 'Yes'
else:
return 'No'

To me the else is adding unneeded noise, I would just write:

if a==b:
return 'Yes'

return 'No'
apart from it being a few more line breaks and an additional
return statement? The inverted form is not more readable per
se (in fact, quite the opposite), and I would even suggest to
minimise its use even in languages like C++ and Java. The Python
syntax is even worse since it not only inverts the order of
return statement and conditional check, but it also puts the
conditional between the two results.

I use(d) the if ... else as follows (per Programming in Python 3):

list = [] if list is None else list

in Perl I would've written:

defined $list or $list = [];

Which I prefer over:

$list = [] unless defined $list;

and more over:

$list = [] if not defined $list;

To me the first Perl form reads as a pre-condition: the list must be
defined *or* make it so.

And maybe you're right, the Python one could've been written:

if list is None:
list = []

which looks, now, also more readable to me as well.
Sorry, but you have just underlined my point, in fact. If it's
discouraged by experts, then of course the question must be
valid why such a feature even exists (okay, apart from 'it
seemed like a good idea at the time').

I guess the latter. Perl has quite some things that in retrospect
could've been done better. On the other hand, Perl developers are very
fanatic about backwards compatibility, which makes it hard to remove
stuff like unless.

On top of that Perl can't be statically analyzed, meaning you can't just
write a perl4to5 or perl510to512 converter.
And more importantly (and
more on-topic here), why we have to have an analogon in Python.

My point. You can sufficiently argue what's wrong with if..else in
Python 3 without dragging Perl into it and staying in Python context. I
am both a Perl and (learning) Python programmer, and to be honest I get
very tired of the somewhat weekly

omg Perl suxxxorsss!!11111

Each language has its own suckage. There are several reasons why while I
am learning Python I also keep updating my Perl skills ;-).
 
R

Russ P.

Chris said:
Hi, how can I write the popular C/JAVA syntax in Python?
Java example:
   return (a==b) ? 'Yes' : 'No'
My first idea is:
   return ('No','Yes')[bool(a==b)]
Is there a more elegant/common python expression for this?
Yes, Python has ternary operator-like syntax:
return ('Yes' if a==b else 'No')
Note that this requires a recent version of Python.

     Who let the dogs in?  That's awful syntax.

                                        John Nagle

Baloney. The Python ternary syntax is perfectly fine. The "if" could
have been put in front, as in Scala:

return if a == b "yes" else "no"

but either way is fine and perfectly readable as far as I am concerned.
 
T

Tim Chase

John said:
And maybe you're right, the Python one could've been written:

if list is None:
list = []

which looks, now, also more readable to me as well.

Though there's a slight difference[1], I'd usually use

lst = lst or []

for your particular initialization use case.

-tkc

[1]
Difference being
>>> lst = []
>>> other = lst
>>> if lst is None: # your code
... lst = []
... ([42], [42])
>>> lst = []
>>> other = lst
>>> lst = lst or [] # my proposal
>>> other.append(42)
>>> lst, other
([], [42])
 
P

Peter Otten

Pierre said:
I'm surprised nobody proposed a solution with itertools ;-)

next(itertools.takewhile(lambda _: a == b, ["yes"]), "no")

You spoke to soon :)

Peter
 
J

Joaquin Abian

In message <7316f3d2-bcc9-4a1a-8598-




Why would you say that’s ugly?

By the way, you don’t need the parentheses.

Lawrence,
maybe it was not the perfect adjective. I meant 'not beautiful'
because for me it is not an expression I can easily read. It is not
internalized in my brain. I know how to use it because I learnt how to
do it time ago(in Learning Python) but always I have to think how it
works (like a mental translation). For me the other alternative
expresion is more readable:

take_it if you_have_it else search_for_it

this was already in my brain before I started writing python code.
Thus, I prefer this option for my code. On the other hand, in my post,
I proposed the and/or style because I found interesting how
symmetrical it was with the one the OP was refering:

(a==b) ? 'Yes' : 'No'
(a==b) and 'Yes' or 'No'


I know, I could write it without parenthesis but it seems more
naturally organized with it and I read it faster and clearly. I dont
know exactly why but it seems also safer to me.

Joaquin
 
D

Den

John said:
Chris said:
Hi, how can I write the popular C/JAVA syntax in Python?
Java example:
   return (a==b) ? 'Yes' : 'No'
My first idea is:
   return ('No','Yes')[bool(a==b)]
Is there a more elegant/common python expression for this?
Yes, Python has ternary operator-like syntax:
return ('Yes' if a==b else 'No')
Note that this requires a recent version of Python.
    Who let the dogs in?  That's awful syntax.

Yes, that's deliberately awful syntax. Guido designed it that way to
ensure that people didn't aver-use it, thereby reducing the readability
of Python applications. Speaking purely personally I hardly ever use it,
but don't dislike it.

regards
 Steve
--
Steve Holden           +1 571 484 6266   +1 800 494 3119
See PyCon Talks from Atlanta 2010  http://pycon.blip.tv/
Holden Web LLC                http://www.holdenweb.com/
UPCOMING EVENTS:        http://holdenweb.eventbrite.com/

I've been following this thread for a few days now. My thoughts are
that, in view of a long known widely used syntax for this operator,
python's syntax seems like change for change sake. If current
programing paradigm provides that particular trinary operator, why
should python's be different from the previously well known one.

For instance, no reasonable language designer would, now, use post-fix
(I know about Forth) or allow only +=, -=, /=, etc. assignments ONLY.
(Just as no reasonable car designer would put the accelerator pedal on
the left.) There are conventions which should span products. Yes
python has the trinary operator and it's not going to change, but this
seems like a bit of petulance on the part of the designer.

Den
 
S

Steve Holden

Den wrote:
[...]
I've been following this thread for a few days now. My thoughts are
that, in view of a long known widely used syntax for this operator,
python's syntax seems like change for change sake. If current
programing paradigm provides that particular trinary operator, why
should python's be different from the previously well known one.
Because the "long known widely used syntax" has been responsible for
some of the most incomprehensible and buggy code in the known universe. \
For instance, no reasonable language designer would, now, use post-fix
(I know about Forth) or allow only +=, -=, /=, etc. assignments ONLY.
(Just as no reasonable car designer would put the accelerator pedal on
the left.) There are conventions which should span products. Yes
python has the trinary operator and it's not going to change, but this
seems like a bit of petulance on the part of the designer.
That argument could easily be extended to suggesting that there should
be no new languages at all. Guido made the specific choice of this
syntax precisely to try and ensure that the ternary (not trinary)
operator wasn't abused the way it has been in C (and later C#). He is a
language designer with a fine sense of readability, and I personally
respect his decision.

This StackOverflow thread

http://stackoverflow.com/questions/1763543/ternary-operator-associativity-in-c-can-i-rely-on-it

is just one example of the time that gets wasted.

But then I suppose that this thread just exemplifies that people will
find something else to waste their time on if you don't encourage them
to abuse the ternary operator.

regards
Steve
 
S

Steven D'Aprano

I've been following this thread for a few days now. My thoughts are
that, in view of a long known widely used syntax for this operator,
python's syntax seems like change for change sake. If current
programing paradigm provides that particular trinary operator, why
should python's be different from the previously well known one.

Yes, I agree, we should be using the previously well known syntax:

condition -> value_if_true, value_if_false

which was introduced by BCPL in 1966.

For instance, no reasonable language designer would, now, use post-fix
(I know about Forth)

Do you also know about Postscript, Factor, Joy and Cat, to mention only a
few? And also the native language of Hewlett-Packard scientific
calculators, RPL.


or allow only +=, -=, /=, etc. assignments ONLY.
(Just as no reasonable car designer would put the accelerator pedal on
the left.) There are conventions which should span products. Yes
python has the trinary operator and it's not going to change, but this
seems like a bit of petulance on the part of the designer.

Unless you have read the PEP that added the operator to the language, and
the reasons for rejecting the alternatives, you are not qualified to
guess what Guido's motives for choosing the current syntax are.

http://www.python.org/dev/peps/pep-0308/

You might not like it, but I do, and I like it far more than the ugly and
hard to understand C syntax. In English (which has existed for much
longer than C) the question mark punctuation symbol is a sentence
terminator, not a separator between clauses, so using ? as an operator
has always looked strange and disturbing to me.
 
S

Steve Howell

Hi, how can I write the popular C/JAVA syntax in Python?

Java example:
    return (a==b) ? 'Yes' : 'No'

; first idea is:
    return ('No','Yes')[bool(a==b)]

Is there a more elegant/common python expression for this?

The ironic thing about the ternary operator is that it is not really
ternary; it's binary. Even just making an expression from a binary
operator inevitably leads to syntax hell.

There is a principle of programming that I would like to coin, which
is the "Tyranny of Three."

It is impossible to code for any expression that has three possible
values in any kind of elegant way. It's just impossible. Try to code
the bowling game without tearing out your teeth--three conditions:
strike, spare, or normal.

The tyranny of three is that 3 is too small for an elegant N-based
solution and too large for a simple condition.
 
S

Steven D'Aprano

The ironic thing about the ternary operator is that it is not really
ternary; it's binary. Even just making an expression from a binary
operator inevitably leads to syntax hell.

There is a principle of programming that I would like to coin, which is
the "Tyranny of Three."

It is impossible to code for any expression that has three possible
values in any kind of elegant way. It's just impossible. Try to code
the bowling game without tearing out your teeth--three conditions:
strike, spare, or normal.

The tyranny of three is that 3 is too small for an elegant N-based
solution and too large for a simple condition.


I'm afraid I don't understand any of that. Can you explain further?

How is the ternary operator "not really ternary, it's binary"? It
requires three arguments, not two, which makes it ternary. In Python
syntax:

value1 if flag else value2

or in C:

flag ? value1 : value2

You say that "Even just making an expression from a binary operator
inevitably leads to syntax hell."

I don't understand what you mean. What is so hellish about any of these?

a + b # infix
a b + # postfix, familiar to anyone who has programmed HP calculators
add(a, b) # prefix function notation
+ a b # prefix
add a to b # verbose English-like


Well, perhaps the infix notation counts as "unusual", and the last as
"too verbose", but hellish?
 
S

Steve Howell

I'm afraid I don't understand any of that. Can you explain further?

How is the ternary operator "not really ternary, it's binary"? It
requires three arguments, not two, which makes it ternary. In Python
syntax:

Of course, I understand that the ternary operator has three arguments,
but it only has two possible outcomes.

You asked me to elaborate on the "Tyranny of Three." Let's say you
have three possible outcomes.

In some languages you would write something like this:

mark = (rolls == 1) && (pins == 10) ? 'strike' :
(rolls == 2) && (pins == 10) ? 'spare' :
'normal'

Many people consider the above very ugly, so they write it like so:

if pins == 10:
if rolls == 1:
return 'strike'
else:
return 'spare'
else:
return 'normal'

Then the next programmer comes along and "cleans up":

if pins == 10:
return 'strike' if rolls == 1 else 'spare'
else:
return 'normal'

Then there is this alternative:

if rolls == 2:
return 'spare' if pins == 10 else 'normal'
else:
return 'strike'

And then:

if rolls == 2:
if pins == 10
return 'spare'
else
return 'normal
else:
return 'strike'

Or even this:

return 'strike' if rolls == 1 else ('spare' if pins == 10 else
'normal')

The "Tyranny of Three" refers to a problem where there are an infinite
number of valid solutions, but none of them have any essential beauty,
so they lead to endless nitpicking and code churn.
 
S

Steve Holden

Steve said:
On Apr 2, 2:04 am, Steven D'Aprano <st...@REMOVE-THIS-
cybersource.com.au> wrote: [...]
How is the ternary operator "not really ternary, it's binary"? It
requires three arguments, not two, which makes it ternary. In Python
syntax:

Of course, I understand that the ternary operator has three arguments,
but it only has two possible outcomes.
That doesn't make it a binary operator. Otherwise what's long
multiplication, which has an infinite number of possible outcomes?
You asked me to elaborate on the "Tyranny of Three." Let's say you
have three possible outcomes.

In some languages you would write something like this:

mark = (rolls == 1) && (pins == 10) ? 'strike' :
(rolls == 2) && (pins == 10) ? 'spare' :
'normal'

Many people consider the above very ugly, so they write it like so:

if pins == 10:
if rolls == 1:
return 'strike'
else:
return 'spare'
else:
return 'normal'

Then the next programmer comes along and "cleans up":

if pins == 10:
return 'strike' if rolls == 1 else 'spare'
else:
return 'normal'

Then there is this alternative:

if rolls == 2:
return 'spare' if pins == 10 else 'normal'
else:
return 'strike'

And then:

if rolls == 2:
if pins == 10
return 'spare'
else
return 'normal
else:
return 'strike'

Or even this:

return 'strike' if rolls == 1 else ('spare' if pins == 10 else
'normal')

The "Tyranny of Three" refers to a problem where there are an infinite
number of valid solutions, but none of them have any essential beauty,
so they lead to endless nitpicking and code churn.
The Real Programmer (tm) simply chooses one, implements it and moves on.
While philosophical discussions are interesting they don't pay the bills.

regards
Steve
 
S

Steve Howell

Of course, I understand that the ternary operator has three arguments,
but it only has two possible outcomes.

You asked me to elaborate on the "Tyranny of Three."  Let's say you
have three possible outcomes.

In some languages you would write something like this:

mark = (rolls == 1) && (pins == 10) ? 'strike' :
       (rolls == 2) && (pins == 10) ? 'spare' :
                                      'normal'

Many people consider the above very ugly, so they write it like so:

  if pins == 10:
     if rolls == 1:
        return 'strike'
     else:
        return 'spare'
  else:
     return 'normal'

Then the next programmer comes along and "cleans up":

  if pins == 10:
    return 'strike' if rolls == 1 else 'spare'
  else:
    return 'normal'

Then there is this alternative:

  if rolls == 2:
    return 'spare' if pins == 10 else 'normal'
  else:
    return 'strike'

And then:

  if rolls == 2:
    if pins == 10
      return 'spare'
    else
      return 'normal
  else:
    return 'strike'

Or even this:

   return 'strike' if rolls == 1 else ('spare' if pins == 10 else
'normal')

The "Tyranny of Three" refers to a problem where there are an infinite
number of valid solutions, but none of them have any essential beauty,
so they lead to endless nitpicking and code churn.

I forgot this one:

def obfuscated_triager(rolls, pins,
lookup = ['normal'] * 10 + ['strike'] + [None] * 9 + ['spare']
):
return lookup[rolls * pins]
 
S

Steve Howell

Steve said:
On Apr 2, 2:04 am, Steven D'Aprano <st...@REMOVE-THIS-
cybersource.com.au> wrote: [...]
How is the ternary operator "not really ternary, it's binary"? It
requires three arguments, not two, which makes it ternary. In Python
syntax:
Of course, I understand that the ternary operator has three arguments,
but it only has two possible outcomes.

That doesn't make it a binary operator. Otherwise what's long
multiplication, which has an infinite number of possible outcomes?

Ok, it's not a binary operator. I just meant it only really selects
from two possible expressions, so you would think there would be one
good way to express that in code, but of course any variation of the
ternary operator leads to endless debates.
The Real Programmer (tm) simply chooses one, implements it and moves on.
While philosophical discussions are interesting they don't pay the bills.

Agreed. The nitpicking and code churn tends to come up when you have
multiple programmers with different aesthetics, although sometimes
even the solo programmer can get overly fiddly.
 
T

Tim Chase

Steve said:
I forgot this one:

def obfuscated_triager(rolls, pins,
lookup = ['normal'] * 10 + ['strike'] + [None] * 9 + ['spare']
):
return lookup[rolls * pins]

Bah...no need to be _quite_ so obscure:
def triager(rolls, pins):
return {
(1, 10):'strike',
(2,10):'spare',
(2,0):'wow, you stink',
}.get((rolls, pins), 'normal')


;-)

-tkc
 
S

Steve Howell

Steve said:
I forgot this one:
def obfuscated_triager(rolls, pins,
        lookup = ['normal'] * 10 + ['strike'] + [None] * 9 + ['spare']
        ):
    return lookup[rolls * pins]

Bah...no need to be _quite_ so obscure:
   def triager(rolls, pins):
     return {
       (1, 10):'strike',
       (2,10):'spare',
       (2,0):'wow, you stink',
       }.get((rolls, pins), 'normal')

;-)

Well played.
 
S

Steven D'Aprano

Of course, I understand that the ternary operator has three arguments,
but it only has two possible outcomes.

But the number of outcomes is not what the "binary" in binary operator
refers to. It's the number of arguments.

You asked me to elaborate on the "Tyranny of Three." Let's say you have
three possible outcomes.

In some languages you would write something like this:

mark = (rolls == 1) && (pins == 10) ? 'strike' :
(rolls == 2) && (pins == 10) ? 'spare' :
'normal'

Not if you held a gun to my head *wink*

Many people consider the above very ugly, so they write it like so:
[snip multiple alternative ways of choosing between three alternatives]

All very interesting, but I don't see why you are singling out three
alternatives as particularly difficult. Not all choices between three
possible results are hard to code:

choice = some_integer % 3 # returns 0, 1, or 2.

and choosing between two results isn't necessarily simple either, e.g.
the rules of protocol. Deciding which of two people outrank the other can
be *very* complicated. Does a king outrank a pope? What about a
president? Does a prince of some two-bit speck of dirt outrank a senator
of a superpower? People have worked out (by which I mean, "made up")
rules for all these and more, and they still can't always agree on who
ranks who. International negotiations have floundered and collapsed
because the parties couldn't agree which ambassador got the chair at the
head of the table nearest the door...

You are absolutely right to say that some problems don't have an elegant
solution, but I think you're wrong to single out "three" as special.
 
K

kj

In said:
John said:
Chris said:
Hi, how can I write the popular C/JAVA syntax in Python?

Java example:
return (a==b) ? 'Yes' : 'No'

My first idea is:
return ('No','Yes')[bool(a==b)]

Is there a more elegant/common python expression for this?

Yes, Python has ternary operator-like syntax:
return ('Yes' if a==b else 'No')

Note that this requires a recent version of Python.

Who let the dogs in? That's awful syntax.
Yes, that's deliberately awful syntax. Guido designed it that way to
ensure that people didn't aver-use it, thereby reducing the readability
of Python applications.

Is that for real??? It's the QWERTY rationale all over again. Swell.

"Let's preserve readability by making the syntax so ugly that people
won't use it."??? That's just perverse. (It would have been more
reassuring if the reason had been simply that Guido has an inexplicable
dislike of ternary expressions just like one may have an inexplicable
dislike of Broadway musicals.)

First, I don't understand why ternary expressions are inherently
hard to read, and therefore must be discouraged in the name of
overall code readability. Sure, one can write impenetrable ternary
expressions, but one can write impenetrable binary expressions or
impenetrable anything else, even in Python. That the expression
is ternary has nothing to do with it.

Second, sticking the test between the two alternatives goes against
a vast tradition in programming languages. This tradition inevitably
fosters habits and expectations when reading code, so going against
it automatically makes code less readable to all who were educated
in that tradition. Consider, for example, the readability of the
following if statement in some hypothetical language:

begin:
# this branch will be executed if test() (see below) evaluates
# to true
x = y + z
a = b * x + c
i = j - k
p = log(q)
if test() else:
x = -(y + z)
a = b * x + 2 * c
i = j + k
p = -log(q)

If you find this hard to read (I do), the quetion is "why?". For
me it's because, maybe through years of reading code, I've developed
a habit that says: when you run into a fork in the logic, first
understand what the decision hinges on. Therefore, my brain will
start hunting for that test, and it sucks to have to find it buried
somewhere in the middle. (Sure, one could justify this horrible
syntax with an argument reminiscent of the one you gave for "A if
X else B". It goes like this: long blocks of code should be avoided
in the name of readability; this syntax discourages long blocks of
code because one doesn't want to skip too far ahead to find that
test. Ergo the end result is improved readability. That's just
nuts.)

Anyway, I don't know of any other language that puts the test
between the alternatives. No doubt there's one out there, with
emphasis on "out there"...

~K
 
J

John Bokma

kj said:
Anyway, I don't know of any other language that puts the test
between the alternatives. No doubt there's one out there, with
emphasis on "out there"...

Perl has something that has IMO somewhat the same problem:

print "Hello, world!\n" if $some_condition;

I prefer most of the time:

$some_condition and print "Hello, world!\n";

Or even:

$some_condition
and print "Hello, world!\n";

Moreover, instead of:

$x = 'some value' unless defined $x;

I prefer

defined $x
or $x = 'some value';

I read the latter as: $x must be defined, otherwise some value must be
assigned to it, like a precondition.

YMMV,
 

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,780
Messages
2,569,608
Members
45,241
Latest member
Lisa1997

Latest Threads

Top