|
|
|
|
|
|
| Author |
Message |
Donn Cave *nix forums Guru Wannabe
Joined: 20 Feb 2005
Posts: 172
|
Posted: Mon Jul 17, 2006 9:16 pm Post subject:
Re: Coding style
|
|
|
In article <mailman.8257.1153158306.27775.python-list@python.org>,
Steve Holden <steve@holdenweb.com> wrote:
| Quote: | tac-tics wrote:
....
I'd say the second one. Empty lists are not false. They are empty.
Long live dedicated boolean data types.
Take them off to where they belong!
|
Tac-tics is right, an empty list is not False.
Anyway, just for some variety, I think (2) is preferrable
to (1), as is the following
while 1:
try:
lst.pop()
except IndexError:
break
Rather than blindly apply familiar patterns to our work,
I think everyone would agree that coding style in matters
like this should follow the underlying point of the code.
In this case, the body of the test refers implicitly to
the length of the list, since .pop() -> (list[a], list[:a])
where a is (len(list) - 1) It's therefore quite appropriate
for the test to be length.
Donn Cave, donn@u.washington.edu |
|
| Back to top |
|
 |
Erik Max Francis *nix forums Guru Wannabe
Joined: 08 Mar 2005
Posts: 251
|
Posted: Mon Jul 17, 2006 9:21 pm Post subject:
Re: Coding style
|
|
|
Donn Cave wrote:
| Quote: | Tac-tics is right, an empty list is not False.
|
But that's not what he said. He said it was "not false." That's wrong.
It's false. It's just not False.
--
Erik Max Francis && max@alcyone.com && http://www.alcyone.com/max/
San Jose, CA, USA && 37 20 N 121 53 W && AIM erikmaxfrancis
The meaning of life is that it stops.
-- Franz Kafka |
|
| Back to top |
|
 |
Bob Greschke *nix forums beginner
Joined: 18 May 2005
Posts: 28
|
Posted: Mon Jul 17, 2006 9:24 pm Post subject:
Re: Coding style
|
|
|
<rurpy@yahoo.com> wrote in message
news:1153168968.995422.198360@m73g2000cwd.googlegroups.com...
| Quote: | PTY wrote:
Which is better?
lst = [1,2,3,4,5]
while lst:
lst.pop()
OR
while len(lst) > 0:
lst.pop()
A dozen posts, but nobody has posted the right
answer yet, so I will :-)
It doesn't matter -- use whichever you prefer (*)
This is an angels on the head of a pin issue.
(*) -- If your code is part of an existing body of
code that uses one or the other style consistently,
then you should do the same.
|
I'd go even one step further. Turn it into English (or your favorite
non-computer language):
1. While list, pop.
2. While the length of the list is greater than 0, pop.
Which one makes more sense? Guess which one I like. CPU cycles be damned.
:)
Bob |
|
| Back to top |
|
 |
PTY *nix forums beginner
Joined: 17 Jul 2006
Posts: 4
|
Posted: Mon Jul 17, 2006 10:34 pm Post subject:
Re: Coding style
|
|
|
Bob Greschke wrote:
| Quote: | rurpy@yahoo.com> wrote in message
news:1153168968.995422.198360@m73g2000cwd.googlegroups.com...
PTY wrote:
Which is better?
lst = [1,2,3,4,5]
while lst:
lst.pop()
OR
while len(lst) > 0:
lst.pop()
A dozen posts, but nobody has posted the right
answer yet, so I will :-)
It doesn't matter -- use whichever you prefer (*)
This is an angels on the head of a pin issue.
(*) -- If your code is part of an existing body of
code that uses one or the other style consistently,
then you should do the same.
I'd go even one step further. Turn it into English (or your favorite
non-computer language):
1. While list, pop.
2. While the length of the list is greater than 0, pop.
Which one makes more sense? Guess which one I like. CPU cycles be damned.
:)
Bob
|
It looks like there are two crowds, terse and verbose. I thought terse
is perl style and verbose is python style. BTW, lst = [] was not what
I was interested in I was asking whether it was better style to
use len() or not. |
|
| Back to top |
|
 |
tactics40@gmail.com *nix forums beginner
Joined: 13 Jun 2006
Posts: 33
|
Posted: Tue Jul 18, 2006 12:42 am Post subject:
Re: Coding style
|
|
|
dwelch91 wrote:
| Quote: | tac-tics wrote:
I'd say the second one. Empty lists are not false. They are empty. Long
live dedicated boolean data types.
Uh, no, empty lists are False in a boolean context:
http://docs.python.org/lib/truth.html
-Don
|
Perhaps I should have specified it like this:
| Quote: | empty_list = []
empty_list is not False
True |
I'm well aware that both of these snippets does the same thing. I'm
just spouting my opinion that lists and integers are not tests, and in
an ideal world (Java??? X-) if statements support only boolean types.
DISCLAIMER: I do not promote the use of Java. |
|
| Back to top |
|
 |
Erik Max Francis *nix forums Guru Wannabe
Joined: 08 Mar 2005
Posts: 251
|
Posted: Tue Jul 18, 2006 12:46 am Post subject:
Re: Coding style
|
|
|
tac-tics wrote:
| Quote: | I'm well aware that both of these snippets does the same thing. I'm
just spouting my opinion that lists and integers are not tests, ...
|
No, but testing their Boolean nature _is_ a test. Aggregate objects in
Python are true if they are non-empty, and false if they are empty.
That is reasonable, not uncommon a convention, and quite useful for
exactly the situations you were talking about. That convention exists
_so that_ writing::
if aContainer:
... container is not empty ...
is meaningful and convenient. So the answer to the original question
was, "The first one." Feel free to write it the other way with an
explicit test, but it's not Pythonic.
--
Erik Max Francis && max@alcyone.com && http://www.alcyone.com/max/
San Jose, CA, USA && 37 20 N 121 53 W && AIM erikmaxfrancis
Life is a toy made of glass; it appears to be of inestimable price,
but in reality it is very cheap. -- Pietro Aretino, 1537 |
|
| Back to top |
|
 |
Patrick Maupin *nix forums beginner
Joined: 23 Jun 2005
Posts: 32
|
Posted: Tue Jul 18, 2006 2:44 am Post subject:
Re: Coding style
|
|
|
PTY wrote:
| Quote: | It looks like there are two crowds, terse and verbose. I thought terse
is perl style and verbose is python style. BTW, lst = [] was not what
I was interested in I was asking whether it was better style to
use len() or not.
|
It's not canonical Python to use len() in this case. From PEP 8:
- For sequences, (strings, lists, tuples), use the fact that empty
sequences are false.
Yes: if not seq:
if seq:
No: if len(seq)
if not len(seq)
The whole reason that a sequence supports testing is exactly for this
scenario. This is not an afterthought -- it's a fundamental design
decision of the language.
Regards,
Pat |
|
| Back to top |
|
 |
pavlovevidence@gmail.com *nix forums beginner
Joined: 17 Jul 2006
Posts: 17
|
Posted: Tue Jul 18, 2006 4:45 am Post subject:
Re: Coding style
|
|
|
PTY wrote:
| Quote: | Which is better?
lst = [1,2,3,4,5]
while lst:
lst.pop()
OR
while len(lst) > 0:
lst.pop()
|
I'm going to go against general opinion and suggest using "len(lst)>0",
though this is not a good example of why I think that.
In practice, I'd say the former is less generic. No, that's not a
typo.
If you were to write a function that expects a list (and actually uses
the list interface, indexing and such, rather than merely passing it
off to another function), the function would almost certainly fail if
you were to pass in an integer or some other non-sequence type.
However, functions expecting a list have a decent chance of working if
you were to pass in a numpy array.
But if you were to write "if lst" instead of "if len(lst)>0", then
you've just ensured your function will fail for numpy arrays. But you
get no benefit in genericity, because non-sequence types almost
certainly wouldn't work anyways.
Therefore, the only time I'd recommend using "if lst" is if all you're
doing is passing it to other functions.
Carl Banks |
|
| Back to top |
|
 |
pavlovevidence@gmail.com *nix forums beginner
Joined: 17 Jul 2006
Posts: 17
|
Posted: Tue Jul 18, 2006 4:53 am Post subject:
Re: Coding style
|
|
|
Patrick Maupin wrote:
| Quote: | PTY wrote:
It looks like there are two crowds, terse and verbose. I thought terse
is perl style and verbose is python style. BTW, lst = [] was not what
I was interested in I was asking whether it was better style to
use len() or not.
It's not canonical Python to use len() in this case. From PEP 8:
- For sequences, (strings, lists, tuples), use the fact that empty
sequences are false.
Yes: if not seq:
if seq:
No: if len(seq)
if not len(seq)
The whole reason that a sequence supports testing is exactly for this
scenario. This is not an afterthought -- it's a fundamental design
decision of the language.
|
That might have made sense when Python and string, list, tuple were the
only sequence types around.
Nowadays, Python has all kinds of spiffy types like numpy arrays,
interators, generators, etc., for which "empty sequence is false" just
doesn't make sense. If Python had been designed with these types in
mind, I'm not sure "empty list is false" would have been part of the
language, let alone recommend practice.
Carl Banks |
|
| Back to top |
|
 |
pavlovevidence@gmail.com *nix forums beginner
Joined: 17 Jul 2006
Posts: 17
|
Posted: Tue Jul 18, 2006 5:13 am Post subject:
Re: Coding style
|
|
|
PTY wrote:
| Quote: | Which is better?
lst = [1,2,3,4,5]
while lst:
lst.pop()
OR
while len(lst) > 0:
lst.pop()
|
Here's another reason not to use "if lst". Say you have a function
that looks like this:
def process_values(lst):
if not lst:
return
do_expensive_initialization_step()
for item in lst:
do_something_with(item)
do_expensive_finalization_step()
That works, right? No problem, right?
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.
If we had used "if len(list)>0", we'd have gotten a nice exception
telling us that a generator is not welcome. Then we'd have changed the
argument to a list comprehension, or better, changed the function to
work for any iterator.
Carl Banks |
|
| Back to top |
|
 |
Paul Rubin *nix forums Guru
Joined: 28 Feb 2005
Posts: 1197
|
Posted: Tue Jul 18, 2006 5:40 am Post subject:
Re: Coding style
|
|
|
"Carl Banks" <pavlovevidence@gmail.com> writes:
| Quote: | 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?
As soon as the function uses lst[3] for something, it will crash
if you pass it a sequence like that. Your example is mainly an
argument for static type checking. |
|
| Back to top |
|
 |
pavlovevidence@gmail.com *nix forums beginner
Joined: 17 Jul 2006
Posts: 17
|
Posted: Tue Jul 18, 2006 6:20 am Post subject:
Re: Coding style
|
|
|
Paul Rubin wrote:
| Quote: | "Carl Banks" <pavlovevidence@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.)
| Quote: | As soon as the function uses lst[3] for something,
|
Notice that the function I wrote never indexes the list. It only
iterates.
| Quote: | 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.)
| Quote: | 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 |
|
| Back to top |
|
 |
Peter Otten *nix forums Guru
Joined: 20 Feb 2005
Posts: 464
|
Posted: Tue Jul 18, 2006 6:28 am Post subject:
Re: Coding style
|
|
|
Carl Banks wrote:
| Quote: | def process_values(lst):
if not lst:
return
do_expensive_initialization_step()
for item in lst:
do_something_with(item)
do_expensive_finalization_step()
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.
|
The good news is that the above has a 99 percent chance that it just works
with iterators/generators -- even though the writer may not have been aware
of them/they didn't exist when the code was written...
Peter |
|
| Back to top |
|
 |
pavlovevidence@gmail.com *nix forums beginner
Joined: 17 Jul 2006
Posts: 17
|
Posted: Tue Jul 18, 2006 6:39 am Post subject:
Re: Coding style
|
|
|
Peter Otten wrote:
| Quote: | Carl Banks wrote:
def process_values(lst):
if not lst:
return
do_expensive_initialization_step()
for item in lst:
do_something_with(item)
do_expensive_finalization_step()
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.
The good news is that the above has a 99 percent chance that it just works
with iterators/generators -- even though the writer may not have been aware
of them/they didn't exist when the code was written...
|
There's a litmus test I like to use when justifying something with
percentages: I imagine that I'm presenting it to my boss, and ask
myself if I still expect to have a job the next day. :-)
Yes, I agree with you, it most cases I expect merely unnecessary work.
(Which is not the best news; the best news would be an exception right
away.) That's why I think this is only a "pretty good" reason to use
"if len(lst)>0", not a slam dunk.
Carl Banks |
|
| Back to top |
|
 |
Steve Holden *nix forums Guru
Joined: 22 Feb 2005
Posts: 1255
|
Posted: Tue Jul 18, 2006 6:42 am Post subject:
Re: Coding style
|
|
|
tac-tics wrote:
| Quote: | dwelch91 wrote:
tac-tics wrote:
I'd say the second one. Empty lists are not false. They are empty. Long
live dedicated boolean data types.
Uh, no, empty lists are False in a boolean context:
http://docs.python.org/lib/truth.html
-Don
Perhaps I should have specified it like this:
empty_list = []
empty_list is not False
True
I'm well aware that both of these snippets does the same thing. I'm
just spouting my opinion that lists and integers are not tests, and in
an ideal world (Java??? X-) if statements support only boolean types.
DISCLAIMER: I do not promote the use of Java.
You don't promote use of Python either if you deliberately ignore |
programming paradigms that have stood the test of time. Under what set
of rules could it make sense to test a list for equality with a Boolean
value (note also that capital "B": the word is based on someone's name).
The
if lst:
metaphor is so well established as a means of guarding statements that
should be executed only when there are elements in the list (or other
container, come to that), promoting any other way to perform the test
will only lead to confusion: there should be one (and preferably only
one) obvious way to do it.
regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://holdenweb.blogspot.com
Recent Ramblings http://del.icio.us/steve.holden |
|
| Back to top |
|
 |
Google
|
|
| Back to top |
|
 |
|
|
The time now is Fri Nov 21, 2008 1:12 pm | All times are GMT
|
|
Bad Credit Loans | Neopets Cheats, Games and Neopoints | Car Loan | Mortgages | Credit Cards
|
|
Copyright © 2004-2005 DeniX Solutions SRL
|
|
|
|
Other DeniX Solutions sites:
Unix/Linux blog |
electronics forum |
medicine forum |
science forum |
|
|
Privacy Policy
|
Powered by phpBB © 2001, 2005 phpBB Group
|
|