[Tutor] Re: New to programming question

Andrei project5 at redrival.net
Wed Apr 13 09:25:47 CEST 2005


Ben Markwell <benmarkwell <at> gmail.com> writes:

<snip>
> if prefixes[n] == 'O' or 'Q':

A tip: when working with several boolean (and/or/not) conditions in one test,
it's helpful to use parentheses in order to make sure you get what you expect.
Let me demonstrate.

The example above is equivalent to:

  if (prefixes[n] == 'O') or ('Q')  [1]

but you probably meant to write:

  if prefixes[n] == ('O' or 'Q')    [2]


With the parentheses it's easier to follow what is going on. In case [1], first
prefixes[n] == 'O' is evaluated (which might or might not return a True). Then
('Q') is evaluated (which is True in a boolean context), which means that the
expression is sort of equivalent to:
 
  if (either True or False) or (True)

which is obviously always True.


Case [2] can be regarded in a similar manner. First ('O' or 'Q') is evaluated.
Let's see what this means. Both 'O' and 'Q' are True in a boolean context, but
what is the *result* of ('O' or 'Q')? After all, the result of this operation is
what you compare with prefixes[n]. You probably don't know the answer to this
question and that should trigger some alarm bells: it's never a good sign if you
don't understand your own code :).
Fortunately we have the Python interpreter available:

>>> ('O' or 'Q')
'O'

Aha! Well, this means that approach [2] is the same as:

  if prefixes[n] == 'O'

This is obviously not what you wanted to achieve.

Actually, I've jumped a bit too fast to a conclusion here, by assuming that ('O'
or 'Q') always returns 'O', just because that's what happened in my 1 test on 1
machine on 1 version of Python. This is a dangerous assumption: perhaps
elsewhere it could return 'Q' or True or 1 (all of these are equivalent in a
boolean expression)? 
In this case it turns out that it is correct (you can read the docs to find out
about how it works, or play around in the interpreter to get a feeling for it),
but be careful with such assumptions, they can bite you. For example let's thest
the assumption that a dictionary remembers the order the keys are entered in:

>>> d = {4:0, 5:0, 6:0}
>>> d.keys()
[4, 5, 6]

Look, it does! However, a different test reveals this:

>>> d = {4:0, 5:0, 1:0}
>>> d.keys()
[1, 4, 5]

Aha! So it sorts the keys (both tests support this conclusion). Or does it?

>>> d = {4:0, -1:0, 5:0}
>>> d.keys()
[4, 5, -1]

Nope, not sorted, not ordered - exactly as the Python specification states,
dictionaries are unordered.

Yours,

Andrei



More information about the Tutor mailing list