Coding style

Carl Banks pavlovevidence at gmail.com
Tue Jul 18 02:20:57 EDT 2006


Paul Rubin wrote:
> "Carl Banks" <pavlovevidence at gmail.com> writes:
> > What if you called the function like this:
> >
> >     process_values(x.strip() for x in values_lst)
> >
> > Oops, now we've just gone through an expensive initialization and
> > finalization for nothing (since values_lst was empty).  Maybe some
> > subtle bugs introduced.  If we're lucky, the finalization step will
> > throw an exception.
>
> You've got a function written to take a list arg and are passing it
> something other than a list.  Why do you expect it to work?

I don't expect it to work as is.  Disregarding the test for emptiness
at the beginning, I would expect it to work for any iterable, even if
the author only intended it for a list.  That's the problem: it looks
like it should work for any iterable, but it doesn't.  I would think
it's a pretty easy mistake to make.  (I suspect lots of programmers
don't even realize that empty generator expressions are true.  Even if
they do, it's easy to overlook that test if you're not careful.)

> As soon as the function uses lst[3] for something,

Notice that the function I wrote never indexes the list.  It only
iterates.

> it will crash
> if you pass it a sequence like that.

The particular function I wrote might crash.  Or it might merely do
unnecessary work.  Or it might have subtle bugs.  (OTOH, if it had used
the "if len(lst)>0", it would crash right away; no subtle bugs.)

>  Your example is mainly an
> argument for static type checking.

Not really.  I'm merely putting forth one argument for using "if
len(lst)>0" rather than "if lst".  ISTM the scenerio I described isn't
terribly rare: you write a function that iterates over an iterable, and
carelessly use a test ("if lst") that doesn't work for all iterables,
and the result could lead to subtle bugs.  Which is not as bad as
carelessly using a test ("if len(lst)>0") that doesn't work for all
iterables, and the result is an immediate exception.

I've given two pretty good reasons for using "if len(lst)>0": it allows
functions to be written generically for lists and numpy arrays, and it
catches the rather plausible mistake of testing the truth value an
iterable (which can lead to subtle bugs).  This is contrasted to the
good reasons for using "if lst", which are... um... hmm... saving a few
keystrokes?


Carl Banks




More information about the Python-list mailing list