OR maybe better?
if foo == bar:
...
or foo == baz:
...
or foo == bra:
...
else:
...
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
`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
> 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
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.
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
Do you mean 'elsif' or 'else if'?
so 'elif' is not only shorter, it's clearer.
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.
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
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.
This has the same result, but is shorter and quicker:
args = line.split()
> 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
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
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
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
>
> 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']
>>>
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
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.
Neat -- thanks for sharing this TerryP
Esmail