Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Why ELIF?

5 views
Skip to first unread message

metal

unread,
Oct 11, 2009, 2:47:38 AM10/11/09
to
I wonder the reason for ELIF. it's not aligned with IF, make code ugly
IMHO

OR maybe better?

if foo == bar:
...
or foo == baz:
...
or foo == bra:
...
else:
...

Erik Max Francis

unread,
Oct 11, 2009, 3:07:18 AM10/11/09
to

Because that's uglier. `or` means something completely unrelated in
expressions. Variations of `else if` in `if ... else if ...` chains is
routine in computer languages. Choosing a deliberately different syntax
just for the sake it of is obtuse at best.

--
Erik Max Francis && m...@alcyone.com && http://www.alcyone.com/max/
San Jose, CA, USA && 37 18 N 121 57 W && AIM/Y!M/Skype erikmaxfrancis
And covenants, without the sword, are but words and of no strength to
secure a man at all. -- Thomas Hobbes, 1588-1679

Steven D'Aprano

unread,
Oct 11, 2009, 4:07:27 AM10/11/09
to


`or` has another meaning in Python, and many other languages:

flag = len(mystring) > 10 or count < 50

By the way, if you're testing a single name against a series of
alternatives, it is often better to look up the value in a dictionary:

table = {bar: 23, baz: 42, boop: 73, beep: 124}
value = table[foo]

instead of:

if foo == bar:
value = 23
elif foo == baz:
value = 42
elif ...

You can even provide a default value by using table.get().

--
Steven

Grant Edwards

unread,
Oct 11, 2009, 10:10:49 AM10/11/09
to
On 2009-10-11, metal <meta...@gmail.com> wrote:

> I wonder the reason for ELIF. it's not aligned with IF, make code ugly

It most certainly is aligned with IF:


if cond1:
do this
elif cond2:
do that
else:
do the other

The "if" "elif" and "else" are all aligned in all of the code
I've ever seen.

--
Grant

TerryP

unread,
Oct 11, 2009, 10:45:43 AM10/11/09
to
On Oct 11, 7:07 am, Erik Max Francis <m...@alcyone.com> wrote:
> Because that's uglier.  `or` means something completely unrelated in
> expressions.  Variations of `else if` in `if ... else if ...` chains is
> routine in computer languages.  Choosing a deliberately different syntax
> just for the sake it of is obtuse at best.
>

I agree - first thing I do when learning a language, is find out what
the local brew is, e.g.: if (expr) {block} else if (expr) {block} else
{block}. It is just a part of programming. Which style it uses, is
mostly inconsequential, as long as the language documents the syntax
and behaviour, all is good [sic].

On Oct 11, 8:07 am, Steven D'Aprano <st...@REMOVE-THIS-


cybersource.com.au> wrote:
> By the way, if you're testing a single name against a series of
> alternatives, it is often better to look up the value in a dictionary:
>
> table = {bar: 23, baz: 42, boop: 73, beep: 124}
> value = table[foo]
>
> instead of:
>
> if foo == bar:
> value = 23
> elif foo == baz:
> value = 42
> elif ...
>

my personally favorite is: foo in table, when applicable.

Esmail

unread,
Oct 11, 2009, 11:42:38 AM10/11/09
to pytho...@python.org
Steven D'Aprano wrote:
>
> By the way, if you're testing a single name against a series of
> alternatives, it is often better to look up the value in a dictionary:
>
> table = {bar: 23, baz: 42, boop: 73, beep: 124}
> value = table[foo]
>
> instead of:
>
> if foo == bar:
> value = 23
> elif foo == baz:
> value = 42
> elif ...
>
> You can even provide a default value by using table.get().

cool .. I hadn't seen that. Not working quite at the 'pythonic' level yet
I am not sure I think it's more readable that the if statement. Also, curious
if the dictionary approach is more efficient.

thanks,
Esmail

MRAB

unread,
Oct 11, 2009, 11:50:50 AM10/11/09
to pytho...@python.org
In some other languages, eg Modula-2, it's 'elsif'; the disadvantage
there is that if you were hearing it read out you might ask:

Do you mean 'elsif' or 'else if'?

so 'elif' is not only shorter, it's clearer.

TerryP

unread,
Oct 11, 2009, 2:15:06 PM10/11/09
to
On Oct 11, 3:42 pm, Esmail <ebo...@hotmail.com> wrote:
> cool .. I hadn't seen that. Not working quite at the 'pythonic' level yet
> I am not sure I think it's more readable that the if statement. Also, curious
> if the dictionary approach is more efficient.
>

Somehow I doubt that "Look up X in dictionary D" could ever be more
efficient (in terms of space and time, at least) then "Check if X is
equal to Y". It's not about what you get in runtime but what you get
in monkey time.


Most expressions that would make someone reach for a C-like switch()
statement can be expressed with dictionaries or attributes instead.

Here is a dorks approach to calling a specific function with arguments
based on a command:

args = re.split('\s', line)
cmd = args.pop(0)

if cmd == "ham":
...(args)
elif cmd == "spam":
...(args)
elif cmd == "eggs":
...(args)
else:
raise SyntaxWarning("Syntax error in above program")

Here is more of a look up table approach:

Note: let Commands be a dictionary, such that { "ham" : ...,
"spam" : ..., "eggs" : ... }.

args = re.split('\s', line)
cmd = args.pop(0)

if cmd in Commands:
Commands[cmd](args)
else:
raise SyntaxWarning("Syntax error in above program")


What values does this second approach offer over the first one? The
most obvious one is that the program does more of the work, then the
maintenance programmer. In a more Object-Oriented light, you could
also fetch a member of an object at run time, and use that in place of
a dictionary. Take a look how the standard 'cmd' module dispatches
stuff.

I might take flak here, for writing something like 'dict[key]
(func_args)' instead of something more Pythonic, but the code serves
to express a point, not teach a system of branch of Zen :-P.

--
TerryP.
Just Another Programmer.

Simon Forman

unread,
Oct 11, 2009, 2:52:33 PM10/11/09
to pytho...@python.org

I'll often do that this way:

args = re.split('\s', line)
cmd = args.pop(0)

def no_cmd(*a, **b):


raise SyntaxWarning("Syntax error in above program")

Commands.get(cmd, no_cmd)(args)

~Simon

Mick Krippendorf

unread,
Oct 11, 2009, 3:10:55 PM10/11/09
to
TerryP schrieb:

> Note: let Commands be a dictionary, such that { "ham" : ...,
> "spam" : ..., "eggs" : ... }.
>
> args = re.split('\s', line)
> cmd = args.pop(0)
>
> if cmd in Commands:
> Commands[cmd](args)
> else:
> raise SyntaxWarning("Syntax error in above program")
>
> [...] I might take flak here, for writing something like 'dict[key]

> (func_args)' instead of something more Pythonic, but the code serves
> to express a point, not teach a system of branch of Zen :-P.

But this *is* pythonic. It must be, since Guido has identified it as a
Pattern and named it the Dommand Dispatch Pattern. Also, it is in
perfect compliance to The Zen (import this).

Regards,
Mick.

MRAB

unread,
Oct 11, 2009, 3:33:37 PM10/11/09
to pytho...@python.org
Simon Forman wrote:
[snip]

>
> I'll often do that this way:
>
> args = re.split('\s', line)

This has the same result, but is shorter and quicker:

args = line.split()

Steven D'Aprano

unread,
Oct 11, 2009, 5:43:48 PM10/11/09
to
On Sun, 11 Oct 2009 11:15:06 -0700, TerryP wrote:

> On Oct 11, 3:42 pm, Esmail <ebo...@hotmail.com> wrote:
>> cool .. I hadn't seen that. Not working quite at the 'pythonic' level
>> yet I am not sure I think it's more readable that the if statement.
>> Also, curious if the dictionary approach is more efficient.
>>
>>
> Somehow I doubt that "Look up X in dictionary D" could ever be more
> efficient (in terms of space and time, at least) then "Check if X is
> equal to Y". It's not about what you get in runtime but what you get in
> monkey time.

A single equality check, obviously not.

Now suppose you have 100 conditions to test. Which is faster, one dict
lookup, or up to 100 separate if X == Y tests? (On average, you need to
test half the conditions before finding the match.)

Hint: dicts are used internally by Python for storing names.


> I might take flak here, for writing something like 'dict[key]
> (func_args)' instead of something more Pythonic,


Looking up a first-class function in a dictionary and passing arguments
to it is perfectly Pythonic.

--
Steven

Carl Banks

unread,
Oct 11, 2009, 6:05:24 PM10/11/09
to
On Oct 11, 7:10 am, Grant Edwards <inva...@invalid.invalid> wrote:

> On 2009-10-11, metal <metal...@gmail.com> wrote:
>
> > I wonder the reason for ELIF. it's not aligned with IF, make code ugly
>
> It most certainly is aligned with IF:
>
>   if cond1:
>       do this
>   elif cond2:
>       do that
>   else:
>       do the other
>
> The "if" "elif" and "else" are all aligned in all of the code
> I've ever seen.

The condition in the elif clause is two columns to the right of the
condition in the if clause.

It's a silly thing to worry about, in fact the slight visual
distinctness of it probably helps readability. Some people do get
finicky about columns and try to line things up all the time. It's
frustrating, wasteful, and ultimately hopeless, and sometimes
deceptive (lining things up can suggest relationships where none
exists) so I make it a point not to do it, however prettier it'll make
those two lines.


Carl Banks

Mensanator

unread,
Oct 11, 2009, 7:12:50 PM10/11/09
to
On Oct 11, 5:05�pm, Carl Banks <pavlovevide...@gmail.com> wrote:
> On Oct 11, 7:10�am, Grant Edwards <inva...@invalid.invalid> wrote:
>
> > On 2009-10-11, metal <metal...@gmail.com> wrote:
>
> > > I wonder the reason for ELIF. it's not aligned with IF, make code ugly
>
> > It most certainly is aligned with IF:
>
> > � if cond1:
> > � � � do this
> > � elif cond2:
> > � � � do that
> > � else:
> > � � � do the other
>
> > The "if" "elif" and "else" are all aligned in all of the code
> > I've ever seen.
>
> The condition in the elif clause is two columns to the right of the
> condition in the if clause.

Why does that matter? Isn't whitespace only
significant at the start of a line?

>
> It's a silly thing to worry about, in fact the slight visual
> distinctness of it probably helps readability.

It doesn't, but you're right, it's silly to
worry about.

> �Some people do get
> finicky about columns and try to line things up all the time. �

But you can do it if you really want to:

a = 1
if a > 5:
print a
elif a > 10:
print a / 3
else:
print 'error'

>It's
> frustrating, wasteful, and ultimately hopeless, and sometimes
> deceptive (lining things up can suggest relationships where none
> exists) so I make it a point not to do it, however prettier it'll make
> those two lines.

The above example is of dubious value. Where I
use it is places like

ONE = gmpy.mpz( 1)
TWO = gmpy.mpz( 2)
THREE = gmpy.mpz( 3)
TEN = gmpy.mpz(10)

>
> Carl Banks

Carl Banks

unread,
Oct 11, 2009, 7:43:40 PM10/11/09
to
On Oct 11, 4:12 pm, Mensanator <mensana...@aol.com> wrote:
> On Oct 11, 5:05 pm, Carl Banks <pavlovevide...@gmail.com> wrote:
>
>
>
>
>
> > On Oct 11, 7:10 am, Grant Edwards <inva...@invalid.invalid> wrote:
>
> > > On 2009-10-11, metal <metal...@gmail.com> wrote:
>
> > > > I wonder the reason for ELIF. it's not aligned with IF, make code ugly
>
> > > It most certainly is aligned with IF:
>
> > > if cond1:
> > > do this
> > > elif cond2:
> > > do that
> > > else:
> > > do the other
>
> > > The "if" "elif" and "else" are all aligned in all of the code
> > > I've ever seen.
>
> > The condition in the elif clause is two columns to the right of the
> > condition in the if clause.
>
> Why does that matter? Isn't whitespace only
> significant at the start of a line?

I don't think it matters. I'm explaining what the OP is complaining
about.


> > It's a silly thing to worry about, in fact the slight visual
> > distinctness of it probably helps readability.
>
> It doesn't, but you're right, it's silly to
> worry about.

No it helps me, not much, but a little. Whether the columns line up
or not is a visual clue that can help spot errors. For instance,
noticing that condition1 and contition2 line up might help me spot the
error in the following code (second clause should be elif).

if condition1:
xxx()
if contidion2:
yyy()
else:
zzz()

It might never help you, but that doesn't mean it can't help others.
I can only recall once or twice being alerted to this mistake by
column alignment, and definitely can recall several times where I
missed it in spite of the extra visual clue. All I said is it was a
slight visual clue, not an earth-shattering deal maker.


> > Some people do get
> > finicky about columns and try to line things up all the time.
>
> But you can do it if you really want to:
>
> a          =  1
> if      a  >  5:
>   print a
> elif    a  > 10:
>   print a  /  3
> else:
>   print 'error'

Ugh.


> >It's
> > frustrating, wasteful, and ultimately hopeless, and sometimes
> > deceptive (lining things up can suggest relationships where none
> > exists) so I make it a point not to do it, however prettier it'll make
> > those two lines.
>
> The above example is of dubious value. Where I
> use it is places like
>
> ONE   = gmpy.mpz( 1)
> TWO   = gmpy.mpz( 2)
> THREE = gmpy.mpz( 3)
> TEN   = gmpy.mpz(10)

I never line up columns except when defining some kind of table.
(E.g., PyMemberDef in a C module.) What happens when you have to add
a constant like this:

A_HUNDRED_MILLION = gmmp.mpz(100000000)

Now you have to widen a dozen pair of parentheses, and the readability
suffers when you have all kinds of space separating things:

ONE = gmpy.mpz( 1)

Plus this has the "implied fictional realtionship" problem I mentioned
(although not too dangerous or misleading here). It'd have been
better not to have bothered.


Carl Banks

John Machin

unread,
Oct 11, 2009, 9:34:51 PM10/11/09
to pytho...@python.org
MRAB <python <at> mrabarnett.plus.com> writes:

>
> Simon Forman wrote:
> [snip]
> >
> > I'll often do that this way:
> >

> > args = re.split('\s', line)
>

> This has the same result, but is shorter and quicker:
>
> args = line.split()
>

HUH?

Shorter and quicker, yes, but provides much better functionality; it's NOT the
same result:

>>> line = ' aaa bbb ccc '
>>> import re
>>> re.split('\s', line)
['', '', '', 'aaa', '', '', 'bbb', '', '', 'ccc', '', '', '']
>>> line.split()
['aaa', 'bbb', 'ccc']
>>>


Mensanator

unread,
Oct 11, 2009, 11:35:42 PM10/11/09
to

I would much prefer this

A_HUNDRED_MILLION = gmpy.mpz(100000000)
ONE = gmpy.mpz( 1)

to this

HUMPTY = gmpy.mpz(3876497)
DUMPTY = gmpy.mpz(912350)
ALICE = gmpy.mpz(1278657)
WHT_RABBIT = gmpy.mpz(75648)
CHESHIRE = gmpy.mpz(913237)

anyday. But that's me. The only one who has
to read my code is me and I like to be able to
follow my thoughts at a later date.

>
> Carl Banks

TerryP

unread,
Oct 12, 2009, 12:52:19 AM10/12/09
to
On Oct 11, 9:43 pm, Steven D'Aprano <st...@REMOVE-THIS-

cybersource.com.au> wrote:
> On Sun, 11 Oct 2009 11:15:06 -0700, TerryP wrote:
> > I might take flak here, for writing something like 'dict[key]
> > (func_args)' instead of something more Pythonic,
>
> Looking up a first-class function in a dictionary and passing arguments
> to it is perfectly Pythonic.
>

It's a technique (learned through Perl), that greatly changed the way
I think about writing code. Since then I've looked for ways to tell
programming languages how to work harder, so that we can sit on our
bums more often.


My brain thinks about programming problems more abstractly then any
specific language, so I pay more attention to the art of it, then to
the idiomatic usage of language foo. As such, that also means I look
for good code instead of code that obeys some pattern or mantra - and
have never claimed to know what "Pythonic" code actually looks
like ;).


As I expresssed, the code served make a point not teach. Brevity is
sometimes done for it's own sake. In real code I would do something
more like:

cmd, args = some_self_documenting_and_fully_qualified_function_name
(line)

and that would handle tokenizing the line correctly throughout the
body of code, for invocation anywhere that it is needed. I hate to
repeat myself when I can compose functions instead.

I chose the re.split() on '\s' whitespace bit as a short cut in
expressing what the most common case would have looked like without it
having to detract from the OP's topic. It also (subtly) implies that
one must look beyond the lotus flower in order to obtain enlightenment
\o/.


P.S. Mick Krippendorf, thanks I forgot about 'import this' :-}

--
TerryP.

Esmail

unread,
Oct 12, 2009, 8:16:37 AM10/12/09
to pytho...@python.org
TerryP wrote:
>
> Somehow I doubt that "Look up X in dictionary D" could ever be more
> efficient (in terms of space and time, at least) then "Check if X is
> equal to Y". It's not about what you get in runtime but what you get
> in monkey time.
>
>
> Most expressions that would make someone reach for a C-like switch()
> statement can be expressed with dictionaries or attributes instead.
>
> Here is a dorks approach to calling a specific function with arguments
> based on a command:
>
<...>

> Here is more of a look up table approach:
<...>

Neat -- thanks for sharing this TerryP

Esmail

0 new messages