473,395 Members | 1,502 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Alternative suggestion for conditional expressions (see PEP 308)

Would anyone like to comment on the following idea?

I was just going to offer it as a new PEP until it was suggested that
I post it here for comment & consideration against PEP 308.

I'm far from being a "language internist" (on Python or anything else)
so go easy on me if this is stupid - it just seemed quite elegant to
me as a relative newbie in town :-)

I also havent got a clue whether this would be easy or even possible
to implement even if it was deemed a reasonable idea.

-----------------------------------------------------------------------

Abstract

Implement C-like conditional expressions, but in a more
flexible and "Python-like" way.

Motivation

The lack of conditional expressions combined with the lack
of a 'switch' statement in Python tends to result in lots
of 'if'/'elif' lines which often arent needed and which make
code more verbose and sometimes (where there are a lot of
them) harder to follow and more prone to mistakes than it
needs to be.

This PEP attempts to address that by proposing a
'Pythonesque' conditional expressions language feature
which fits well with existing language features
and the way that conditional expressions are often
simulated in current Python code by using temporary
tuples, lists or dictionaries.
Rationale

It is currently possible to simulate conditional
expressions in Python using constructs with
temporary tuples/lists, such as:

sColorName = ("Black","White")[Color == COLOR_WHITE]

This works, but has two disadvantages:

i) it involves packing and unpacking of a 'temporary'
tuple, eg. ("Black","White") in the above, which
has performance implications

ii) this in turn means that *all* of the possible
final values have to be valid (not just the one
which will be actually selected), which is often
not the case in a more real-world example, eg:

r = (DEFAULT_RESULT, Database.Results[index])
[IsValid(index)]

In the above, 'Database.Results[index]' isn't
defined to be valid if the 'index' value isn't,
which means that this technique cant be used.

Specification

I therefore suggest a variation on the above
syntax such as:

sColorName = ?("Black","White")[Color == COLOR_WHITE]

where the '?' identifies the immediately following
tuple as a "conditional tuple" in which the tuple is
not actually fully evaluated/stored. Instead,
only the element specified by the immediately following
index expression is evaluated and must be valid.

This syntax could also apply to other sequence types,
for example dictionaries:

sColorName = ?{COLOR_RED:"Red",
COLOR_BLUE:"Blue",
COLOR_GREEN:"Green"}[ColorValue]

Again, the conditional sequence is not fully evaluated/stored,
so it doesnt matter if it is large and/or has members which
arent evaluated given an index value which doesnt actually
select them.

Obviously, the above are just simple examples.
Jul 18 '05 #1
8 2251
neblackcat wrote:
Would anyone like to comment on the following idea?
Implement C-like conditional expressions, but in a more
flexible and "Python-like" way. [...] I therefore suggest a variation on the above
syntax such as:

sColorName = ?("Black","White")[Color == COLOR_WHITE]


Funky uses of punctuation are about as non-Pythonic as you
can get, so I doubt this idea would make it past the post...

-Peter
Jul 18 '05 #2
Seems that every one of the examples can be done
with a dictionary.

sColorName = ("Black","White")[Color == COLOR_WHITE]

use dictionary lookup:

colorNameDict={COLOR_WHITE:"White", COLOR_BLACK: "BLACK"}
sColorName=colorNameDict[Color]
and

sColorName = ?{COLOR_RED:"Red",
COLOR_BLUE:"Blue",
COLOR_GREEN:"Green"}[ColorValue]
can be done as:

colorNameDict={COLOR_RED:"Red",
COLOR_BLUE:"Blue",
COLOR_GREEN:"Green"}

sColorName=colorNameDict[ColorValue

you can also handle the "Default/undefined" case as:

colorNameDict={COLOR_RED:"Red",
COLOR_BLUE:"Blue",
COLOR_GREEN:"Green"}

sColorname=ColorNameDict.get(ColorValue, defaultvalue)

or as I often do:

colorNameDict={COLOR_RED:"Red",
COLOR_BLUE:"Blue",
COLOR_GREEN:"Green",
'unknown': 'Unknown'}

sColorname=colorNameDict.get(ColorValue, colorNameDict['unknown'])

Since these dictionaries should be defined once and never
inside a loop, I don't believe that performance is an issue.

You can also simulate a switch statement as follows:

def foo(args):
print "in foo"

def bar(args):
print "in bar"

def hee(args):
print "in hee"

def unknown(args):
print "in unknown"

switchDict={'one': foo, 'two': bar, 'three': hee,
'default': unknown}

switchvalue='one'
switchFunction=switchDict.get(switchvalue, switchvalue['default'])
switchFunction(args)

Again you get excellent performance because dictionary lookups
are blazingly fast. switchDict is only evaluated a single time
(or should be) and is easily extendable by simply adding more
switch values as keys.

Larry Bates
Syscon, Inc.

"neblackcat" <ne********@yahoo.com.au> wrote in message
news:39**************************@posting.google.c om...
Would anyone like to comment on the following idea?

I was just going to offer it as a new PEP until it was suggested that
I post it here for comment & consideration against PEP 308.

I'm far from being a "language internist" (on Python or anything else)
so go easy on me if this is stupid - it just seemed quite elegant to
me as a relative newbie in town :-)

I also havent got a clue whether this would be easy or even possible
to implement even if it was deemed a reasonable idea.

-----------------------------------------------------------------------

Abstract

Implement C-like conditional expressions, but in a more
flexible and "Python-like" way.

Motivation

The lack of conditional expressions combined with the lack
of a 'switch' statement in Python tends to result in lots
of 'if'/'elif' lines which often arent needed and which make
code more verbose and sometimes (where there are a lot of
them) harder to follow and more prone to mistakes than it
needs to be.

This PEP attempts to address that by proposing a
'Pythonesque' conditional expressions language feature
which fits well with existing language features
and the way that conditional expressions are often
simulated in current Python code by using temporary
tuples, lists or dictionaries.
Rationale

It is currently possible to simulate conditional
expressions in Python using constructs with
temporary tuples/lists, such as:

sColorName = ("Black","White")[Color == COLOR_WHITE]

This works, but has two disadvantages:

i) it involves packing and unpacking of a 'temporary'
tuple, eg. ("Black","White") in the above, which
has performance implications

ii) this in turn means that *all* of the possible
final values have to be valid (not just the one
which will be actually selected), which is often
not the case in a more real-world example, eg:

r = (DEFAULT_RESULT, Database.Results[index])
[IsValid(index)]

In the above, 'Database.Results[index]' isn't
defined to be valid if the 'index' value isn't,
which means that this technique cant be used.

Specification

I therefore suggest a variation on the above
syntax such as:

sColorName = ?("Black","White")[Color == COLOR_WHITE]

where the '?' identifies the immediately following
tuple as a "conditional tuple" in which the tuple is
not actually fully evaluated/stored. Instead,
only the element specified by the immediately following
index expression is evaluated and must be valid.

This syntax could also apply to other sequence types,
for example dictionaries:

sColorName = ?{COLOR_RED:"Red",
COLOR_BLUE:"Blue",
COLOR_GREEN:"Green"}[ColorValue]

Again, the conditional sequence is not fully evaluated/stored,
so it doesnt matter if it is large and/or has members which
arent evaluated given an index value which doesnt actually
select them.

Obviously, the above are just simple examples.

Jul 18 '05 #3
Larry Bates wrote:
Seems that every one of the examples can be done
with a dictionary.


While that may be true of the examples given here, it's not true of all
cases. The one possible real advantage of a conditional expression, as
I see it, is shortcutting. In cases where the conditionally-executed
code has side effects, it can be important to ensure that *only* one
branch is evaluated; creating an actual dictionary (whether permanent or
temporary) will execute *all* branches. For example, using neblackcat's
proposed syntax (even though I'm *not* fond of it):

nextline = ?(FileOne.readline(), FileTwo.readline())[whichfile]

In this case, since reading a line from a file advances the filepointer,
executing both will result in a line being "lost" from the non-selected
file. (I realize that in this specific example, one could use the
conditional to select a file object and call readline() on the result of
the conditional; I could also construct examples in which entirely
different operations-with-side-effects are performed on each branch so
that refactoring in that way isn't practical, or one branch is a string
literal and the other has some side-effect, or whatever.)

Note that, while I do think it's important to be aware of this
distinction, I'm not advocating the proposed syntax (I'm rather leery of
using punctuation like that, as Peter Hansen mentions) or even
necessarily advocating for a conditional expression at all. I remain
unconvinced of the need for an expression to do what can already be done
with statements -- a conditional expression may be more concise, but
conciseness more often hampers readability than helps it, and
readability is very important. I've heard the arguments that using a
multiline if/else construct in order to set up parameters for a function
call is ugly, but I personally find that to be no worse than the
ugliness of conditional expressions...

Jeff Shannon
Technician/Programmer
Credit International

Jul 18 '05 #4
On Thu, Jul 15, 2004 at 12:17:08PM -0700, Jeff Shannon wrote:
Larry Bates wrote:
Seems that every one of the examples can be done
with a dictionary.


While that may be true of the examples given here, it's not true of all
cases. The one possible real advantage of a conditional expression, as
I see it, is shortcutting. In cases where the conditionally-executed
code has side effects, it can be important to ensure that *only* one
branch is evaluated; creating an actual dictionary (whether permanent or
temporary) will execute *all* branches. For example, using neblackcat's
proposed syntax (even though I'm *not* fond of it):

nextline = ?(FileOne.readline(), FileTwo.readline())[whichfile]

...


Evaluation of the expressions could be deferred by using callables, like
so:

next = (lambda: fileone.readline(), lambda filetwo.readline())[which]()

Or since in this example both sides of the tuple are already callables:

next = (fileone.readline, filetwo.readline)[which]()

But then really, is writing:

if which: next=fileone.readline()
else: next=filetwo.readline()

all that bad?
Jul 18 '05 #5
I was inclined to support PEP 308, but now wonder whether it's really
needed.

sColorName = ("Black","White")[Color == COLOR_WHITE]

Could be:

sColorName = Color == COLOR_WHITE and "Black" or "White"

which takes avantantage of the short circuit evaluation

sColorName= color == colorwhite and "white" or garbage

This gives the correct result when only the first case needs to be
evalutated.

Colin W.

neblackcat wrote:
Would anyone like to comment on the following idea?

I was just going to offer it as a new PEP until it was suggested that
I post it here for comment & consideration against PEP 308.

I'm far from being a "language internist" (on Python or anything else)
so go easy on me if this is stupid - it just seemed quite elegant to
me as a relative newbie in town :-)

I also havent got a clue whether this would be easy or even possible
to implement even if it was deemed a reasonable idea.

-----------------------------------------------------------------------

Abstract

Implement C-like conditional expressions, but in a more
flexible and "Python-like" way.

Motivation

The lack of conditional expressions combined with the lack
of a 'switch' statement in Python tends to result in lots
of 'if'/'elif' lines which often arent needed and which make
code more verbose and sometimes (where there are a lot of
them) harder to follow and more prone to mistakes than it
needs to be.

This PEP attempts to address that by proposing a
'Pythonesque' conditional expressions language feature
which fits well with existing language features
and the way that conditional expressions are often
simulated in current Python code by using temporary
tuples, lists or dictionaries.
Rationale

It is currently possible to simulate conditional
expressions in Python using constructs with
temporary tuples/lists, such as:

sColorName = ("Black","White")[Color == COLOR_WHITE]

This works, but has two disadvantages:

i) it involves packing and unpacking of a 'temporary'
tuple, eg. ("Black","White") in the above, which
has performance implications

ii) this in turn means that *all* of the possible
final values have to be valid (not just the one
which will be actually selected), which is often
not the case in a more real-world example, eg:

r = (DEFAULT_RESULT, Database.Results[index])
[IsValid(index)]

In the above, 'Database.Results[index]' isn't
defined to be valid if the 'index' value isn't,
which means that this technique cant be used.

Specification

I therefore suggest a variation on the above
syntax such as:

sColorName = ?("Black","White")[Color == COLOR_WHITE]

where the '?' identifies the immediately following
tuple as a "conditional tuple" in which the tuple is
not actually fully evaluated/stored. Instead,
only the element specified by the immediately following
index expression is evaluated and must be valid.

This syntax could also apply to other sequence types,
for example dictionaries:

sColorName = ?{COLOR_RED:"Red",
COLOR_BLUE:"Blue",
COLOR_GREEN:"Green"}[ColorValue]

Again, the conditional sequence is not fully evaluated/stored,
so it doesnt matter if it is large and/or has members which
arent evaluated given an index value which doesnt actually
select them.

Obviously, the above are just simple examples.


Jul 18 '05 #6
Colin J. Williams <cj*@sympatico.ca>
wrote on Fri, 16 Jul 2004 09:49:22 -0400:
I was inclined to support PEP 308, but now wonder whether it's really
needed.
sColorName = ("Black","White")[Color == COLOR_WHITE]
Could be:
sColorName = Color == COLOR_WHITE and "Black" or "White"
which takes avantantage of the short circuit evaluation
sColorName= color == colorwhite and "white" or garbage
This gives the correct result when only the first case needs to be
evalutated.


This works only as long as the results of the (true, false) choices
both evaluate true:
def foo(): .... print "eval foo"
.... return "foo"
.... def bar(): .... print "eval bar"
.... return "bar"
.... False and foo() or bar() eval bar
'bar' True and foo() or bar() eval foo
'foo'

Looks good, right?
def foo(): .... print "eval foo"
.... return ""
.... False and foo() or bar() eval bar
'bar' True and foo() or bar() eval foo
eval bar
'bar'

Alas. Not only does it evaluate both, causing who-knows-what side
effects, it returns the wrong answer. Your Python nuclear missile
launch program goes out of control. All die. O the embarassment.

This is why we do actually need a ternary. It's not that the language
lacks tools for choosing now, but that this behavior is so very easy to
get wrong, and leads to very subtle bugs.

The PEP 308 vote showed that at least 84% of the Python users wanted a
ternary. A second vote between the four major choices would have
obviously ended us up with the (if <cond1>: <expr1> elif <cond2>:
<expr2> ... else: <exprN>) form, which is about as Pythonically
unambiguous as you can get.

At the time, my opinion was that I didn't need a ternary often enough
to care. Sometimes I want to modify some math depending on a boolean,
and in that case I can just treat it as 0 or 1:
5 + 3 * True 8

And the rest of the time, it's easy (if tedious) to just write:
if True: a=foo() .... else: a=bar()
....
eval foo a

''

However, the ease of doing the and...or and ()[] versions wrong, and
how unbelievably ugly the latter is, have changed my mind from "this is
not important" to "this is something Python really does need, after
all".

--
<a href="http://kuoi.asui.uidaho.edu/~kamikaze/"> Mark Hughes </a>
"The void breathed hard on my heart, turning its illusions to ice, shattering
them. Was reborn, then, free to scrawl own design on this morally blank
world. Was Rorschach." --Alan Moore, _Watchmen #6_, "The Abyss Gazes Also"
Jul 18 '05 #7

Flame suit on.

- add a switch-case statement :
I do miss a switch-case in Python.
The interpreter can't really optimize if/elif as a dictionary lookup,
because what if there is a AND or OR clause, or if the object has defined
a __cmp__ method with side effects ? This would be pervert...

switch color:
case 1:
name = 'red'
case 2:
name = 'blue'
case 3:
case 4:
name = 'colorblind'

Could use a 'break' (like in C) or not (cleaner).

- add a switch-case statement which can return a value.
Problem : you need a new keyword for that, which is a bad thing... and it
starts to look like lisp...

I think the ternary operator is a half-baked solution to a more general
problem ; it is useful as a little shortcut like " x ? 'Yes' : 'No' but
doing more with it leads to obfuscation.

Still, something lacks in Python... just like the break-n-levels.

Jul 18 '05 #8
Pierre-Frédéric Caillaud <pe****@free.fr>
wrote on Mon, 19 Jul 2004 19:31:07 +0200:
Flame suit on.
- add a switch-case statement :
I do miss a switch-case in Python.
The interpreter can't really optimize if/elif as a dictionary lookup,
because what if there is a AND or OR clause, or if the object has defined
a __cmp__ method with side effects ? This would be pervert...
switch color:
case 1:
name = 'red'
case 2:
name = 'blue'
case 3:
case 4:
name = 'colorblind'
Could use a 'break' (like in C) or not (cleaner).
- add a switch-case statement which can return a value.
Problem : you need a new keyword for that, which is a bad thing... and it
starts to look like lisp...
Simpler version that already works:
colornames = {
1: "red",
2: "blue",
}
print colornames.get(color, "colorblind")
I think the ternary operator is a half-baked solution to a more general
problem ; it is useful as a little shortcut like " x ? 'Yes' : 'No' but
doing more with it leads to obfuscation.
It's more for selecting between function calls than for constants. A
common idiom with a ternary in Java is:
value = test == null ? null : test.something();

That doesn't happen as often in Python, but choosing between different
methods depending on a flag happens more often.
Still, something lacks in Python... just like the break-n-levels.


At least there's a consistent and easy way to do that. Use
exceptions, or extract your inner loops into a method, and return when
you want to "break out".

--
<a href="http://kuoi.asui.uidaho.edu/~kamikaze/"> Mark Hughes </a>
"Spontaneous deliquescence is now a protected condition under the Americans with
Disabilities Act." -John J. Reilly, "Cthuluism and the Cold War"
Jul 18 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

62
by: Reinhold Birkenfeld | last post by:
Hi, after Guido's pronouncement yesterday, in one of the next versions of Python there will be a conditional expression with the following syntax: X if C else Y which is the same as today's...
5
by: A.M | last post by:
Hi, I am using Python 2.4. I read the PEP 308 at: http://www.python.org/dev/peps/pep-0308/
4
by: Colin J. Williams | last post by:
It would be helpful if the rules of the game were spelled out more clearly. The conditional expression is defined as X if C else Y. We don't know the precedence of the "if" operator. From the...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.