Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > which is more 'pythonic' / 'better' ?

Reply
Thread Tools

which is more 'pythonic' / 'better' ?

 
 
gabor
Guest
Posts: n/a
 
      09-12-2005
hi,

there are 2 versions of a simple code.
which is preferred?


===
if len(line) >= (n+1):
text = line[n]
else:
text = 'nothing'
===


===
try:
text = line[n]
except IndexError:
text = 'nothing'
===


which is the one you would use?

thanks,
gabor
 
Reply With Quote
 
 
 
 
Will McGugan
Guest
Posts: n/a
 
      09-12-2005
gabor wrote:
> hi,
>
> there are 2 versions of a simple code.
> which is preferred?
>
>
> ===
> if len(line) >= (n+1):
> text = line[n]
> else:
> text = 'nothing'
> ===
>
>
> ===
> try:
> text = line[n]
> except IndexError:
> text = 'nothing'
> ===
>
>
> which is the one you would use?


I would actualy use the following for this particular case..

text = line[n:n+1] or 'nothing'

But in general I think it is best to use exceptions like that only where
you expect the code to _not_ throw the exception the majority of
times. Otherwise the simple condition is better. Although I expect there
is not much difference either way..


Will McGugan
--
http://www.kelpiesoft.com
 
Reply With Quote
 
 
 
 
Steven D'Aprano
Guest
Posts: n/a
 
      09-12-2005
On Mon, 12 Sep 2005 12:52:52 +0200, gabor wrote:

> hi,
>
> there are 2 versions of a simple code.
> which is preferred?
>
>
> ===
> if len(line) >= (n+1):
> text = line[n]
> else:
> text = 'nothing'
> ===
>
>
> ===
> try:
> text = line[n]
> except IndexError:
> text = 'nothing'
> ===
>
>
> which is the one you would use?


Personally, I would use either. You say po-ta-to, I say pot-at-o.

try...except... blocks are quick to set up, but slow to catch the
exception. If you expect that most of your attempts will succeed, then the
try block will usually be faster than testing the length of the list
each time.

But if you expect that the attempts to write the line will fail more
frequently, then testing will be quicker.

You will need to do your own testing before hand to find the exact
cut-off, and expect that cut-off to vary according to the Python
implementation and version. But a rough rule of thumb is, if you expect
your code to fail more often than succeed, then test first, otherwise
catch an exception.



--
Steven.

 
Reply With Quote
 
Pierre Barbier de Reuille
Guest
Posts: n/a
 
      09-12-2005
Will McGugan a écrit :
> gabor wrote:
>
>> hi,
>>
>> there are 2 versions of a simple code.
>> which is preferred?
>>
>>
>> ===
>> if len(line) >= (n+1):
>> text = line[n]
>> else:
>> text = 'nothing'
>> ===
>>
>>
>> ===
>> try:
>> text = line[n]
>> except IndexError:
>> text = 'nothing'
>> ===
>>
>>
>> which is the one you would use?

>
>
> I would actualy use the following for this particular case..
>
> text = line[n:n+1] or 'nothing'


.... and you would get either a list of one element or a string ...
I think you wanted to write :

text = (line[n:n+1] or ['nothing'])[0]

However, I wouldn't use that because it is hard to read ... you have to
know Python in great detail to know that:

1 - is the expressions "line[i:j]", i and j are replaced with
"len(line)" if they are greater than "len(line)"
2 - so if n > len(line), then line[n:n+1]" == len[len(line):len(line)]
== []
(it is not evident that line[n:n+1] can give an empty list ...)
3 - empty list evaluate to "False"
4 - the "or" operator returns the first argument evaluating to "true"

So, in the end, you use 3 side-effects of Python in the same small
expression ... (1, 2 and 4)

>
> But in general I think it is best to use exceptions like that only where
> you expect the code to _not_ throw the exception the majority of times.
> Otherwise the simple condition is better. Although I expect there is not
> much difference either way..
>
>
> Will McGugan
> --
> http://www.kelpiesoft.com


What I would do is the following:
- if this happen in a loop, I would, if possible, remove any test and
catch the exception outside the loop !
- otherwise, I would go for the test, as it is more straitforward to read.

Pierre
 
Reply With Quote
 
Will McGugan
Guest
Posts: n/a
 
      09-12-2005
Pierre Barbier de Reuille wrote:

>>
>>I would actualy use the following for this particular case..
>>
>>text = line[n:n+1] or 'nothing'

>
>
> ... and you would get either a list of one element or a string ...
> I think you wanted to write :
>
> text = (line[n:n+1] or ['nothing'])[0]


I was assuming that 'line' would be a string, not a list. Seems more
likely give the name and context.

Will McGugan
--
http://www.kelpiesoft.com
 
Reply With Quote
 
Steven Bethard
Guest
Posts: n/a
 
      09-12-2005
Steven D'Aprano wrote:
> try...except... blocks are quick to set up, but slow to catch the
> exception. If you expect that most of your attempts will succeed, then the
> try block will usually be faster than testing the length of the list
> each time.
>
> But if you expect that the attempts to write the line will fail more
> frequently, then testing will be quicker.
>
> You will need to do your own testing before hand to find the exact
> cut-off, and expect that cut-off to vary according to the Python
> implementation and version. But a rough rule of thumb is, if you expect
> your code to fail more often than succeed, then test first, otherwise
> catch an exception.


FWIW, these are almost exactly my criteria too. Exceptions are for
"exceptional" conditions, that is, things that you expect to happen
infrequently[1]. So if I think the code is going to fail frequently, I
test the condition, but if I think it won't, I use exceptions.

STeVe

[1] Note though that what is "infrequent" in Python might be still
considered "frequent" in other languages. For example, Java's iterators
check the result of a .hasNext() method before each .next() call, while
Python's iterators assume the .next() call will succeed, and simply test
for the "exceptional" condition of a StopIteration exception.
 
Reply With Quote
 
Steve Holden
Guest
Posts: n/a
 
      09-12-2005
Will McGugan wrote:
> Pierre Barbier de Reuille wrote:
>
>
>>>I would actualy use the following for this particular case..
>>>
>>>text = line[n:n+1] or 'nothing'

>>
>>
>>... and you would get either a list of one element or a string ...
>>I think you wanted to write :
>>
>>text = (line[n:n+1] or ['nothing'])[0]

>
>
> I was assuming that 'line' would be a string, not a list. Seems more
> likely give the name and context.
>

I'd say it's much more likely that line is a list of lines, since it
seems improbable that absence of a character should cause a value of
"nothing" to be required.

so-i-say-po-tay-to-ly y'rs - steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC http://www.holdenweb.com/

 
Reply With Quote
 
Michael Hoffman
Guest
Posts: n/a
 
      09-12-2005
Steven Bethard wrote:

> Exceptions are for
> "exceptional" conditions, that is, things that you expect to happen
> infrequently[1]. So if I think the code is going to fail frequently, I
> test the condition, but if I think it won't, I use exceptions.


I think there exceptions (no pun intended) to that rule as well. A
classic example is writing to a file. Even if you expect this to be
impossible, it's best to just create it and trap the exception, thereby
avoiding a race condition.
--
Michael Hoffman
 
Reply With Quote
 
Will McGugan
Guest
Posts: n/a
 
      09-12-2005
Steve Holden wrote:

> I'd say it's much more likely that line is a list of lines, since it
> seems improbable that absence of a character should cause a value of
> "nothing" to be required.


You may be right. I always use plural nouns for collections. To me
'line' would suggest there was just one of them, so I assumed it was string.


Will McGugan
--
http://www.willmcgugan.com
"".join({'*':'@','^':'.'}.get(c,0) or chr(97+(ord(c)-84)%26) for c in
"jvyy*jvyyzpthtna^pbz")
 
Reply With Quote
 
Terry Reedy
Guest
Posts: n/a
 
      09-13-2005

"Will McGugan" <(E-Mail Removed)> wrote in message
news:4325a3fe$0$525$(E-Mail Removed)...
> You may be right. I always use plural nouns for collections.


ditto
> To me 'line' would suggest there was just one of them,
> so I assumed it was string.


I did too.

for line in file('skljflask.txt',r): # or similar

is a common idiom posted here many times.

Terry J. Reedy



 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Kamaelia 0.4.0 RELEASED - Faster! More Tools! More Examples! More Docs! ;-) Michael Python 4 06-26-2006 08:00 AM
Microcontrollers: which one ? which language ? which compiler ? The Jesus of Suburbia NZ Computing 2 02-11-2006 06:53 PM
ADSL WIC support - which NM's, and which IOS versions? Kralizec Craig Cisco 5 12-08-2005 02:20 AM
With a Ruby Yell: more, more more! Robert Klemme Ruby 5 09-29-2005 06:37 AM
Keeping track of which user controls need to be loaded and which not John ASP .Net 0 07-08-2003 09:26 AM



Advertisments