f



which is more 'pythonic' / 'better' ?

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
0
gabor6331 (25)
9/12/2005 10:52:52 AM
comp.lang.python 77058 articles. 6 followers. Post Follow

15 Replies
831 Views

Similar Articles

[PageSpeed] 11

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
0
news7072 (110)
9/12/2005 11:44:56 AM
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.

0
steve24 (1018)
9/12/2005 11:53:15 AM
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
0
9/12/2005 1:17:05 PM
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
0
news7072 (110)
9/12/2005 1:37:31 PM
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.
0
9/12/2005 3:27:01 PM
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/

0
steve73 (4801)
9/12/2005 3:29:33 PM
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
0
cam.ac.uk (454)
9/12/2005 3:41:19 PM
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")
0
news7072 (110)
9/12/2005 3:51:25 PM
"Will McGugan" <news@NOwillmcguganSPAM.com> wrote in message 
news:4325a3fe$0$525$da0feed9@news.zen.co.uk...
> 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



0
tjreedy (5460)
9/13/2005 1:36:16 AM
Terry Reedy wrote:
> "Will McGugan" <news@NOwillmcguganSPAM.com> wrote in message 
> news:4325a3fe$0$525$da0feed9@news.zen.co.uk...
> 
>>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.
> 

i'm sorry ;) it was  a list of strings...

the code was something like:

for line in open('x.y'):
	line = line.split('\t')


a better naming would be better it seems :)

gabor
0
gabor6331 (25)
9/13/2005 6:54:04 AM
"gabor" <gabor@nekomancer.net> wrote in message 
news:433d5$4326783e$c32e4536$22052@news.flashnewsgroups.com...
> i'm sorry ;) it was  a list of strings...
>
> the code was something like:
>
> for line in open('x.y'):
> line = line.split('\t')
>
> a better naming would be better it seems :)

Like 'fields', for a list of fields ;-?

Or your question could have either included the code above or simply 
specified what 'line' was.  Asking clear questions is a learning process.

Terry J. Reedy



0
tjreedy (5460)
9/13/2005 5:55:19 PM
Will McGugan wrote:
> 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

Hey are you a perl programmer?  That looks perlish to me.  A python 
programmer would never use "or" that way (even though it works).  :)

It's okay, I used to be a perl programmer too.  It's nothing to be 
ashamed of. :)

- Ken

0
pythonic (8)
9/13/2005 9:08:27 PM
Ken Seehart wrote:
> Will McGugan wrote:
>> I would actualy use the following for this particular case..
>>
>> text = line[n:n+1] or 'nothing'

> Hey are you a perl programmer?  That looks perlish to me.  A python 
> programmer would never use "or" that way (even though it works).  :)

I don't think that's at all true.  The pattern "somevalue or default" is 
an accepted idiom for returning a default value when "somevalue" is 
False, often used inside __init__ methods to set up attributes.  A most 
common case is like this (inside a class obviously):

def meth(self, things=None):
     self.things = things or []

(The reason you don't just use a keyword argument of "things=[]" should 
be obvious to all but newbies, and they'll learn a lot by researching 
why so I won't say here. ;-)  )

The alternative is fine too, but insisting on it would be pedantic, and 
if you have more than one of these it is definitely less readable (and, 
therefore, not Pythonic):

def meth(self, things=None):
     if things:
         self.things = things
     else:
         self.things = []

> It's okay, I used to be a perl programmer too.  It's nothing to be 
> ashamed of. :)

Ah, now I would disagree with that as well! ;-)

-Peter
0
peter34 (3696)
9/13/2005 9:48:27 PM
Peter Hansen wrote:
> def meth(self, things=None):
>     self.things = things or []
> 
[snip]
> 
> The alternative is fine too, but insisting on it would be pedantic, and 
> if you have more than one of these it is definitely less readable (and, 
> therefore, not Pythonic):
> 
> def meth(self, things=None):
>     if things:
>         self.things = things
>     else:
>         self.things = []

Probably worth pointing out that there is at least one more alternative:

def meth(self, things=None):
     if things is None:
         things = []
     self.things = things

I usually opt for this one, mainly because "things or []" makes me 
nervous -- it has different behavior if the user passes in an empty list:

py> class Things1(object):
....     def __init__(self, things=None):
....         if things is None:
....             things = []
....         self.things = things
....
py> class Things2(object):
....     def __init__(self, things=None):
....         self.things = things or []
....
py> lst = []
py> thing = Things1(lst)
py> thing.things.append(100)
py> thing.things, lst
([100], [100])
py> lst = []
py> thing = Things2(lst)
py> thing.things.append(100)
py> thing.things, lst
([100], [])

That said, I do use "and" and "or" occasionally when I'm sure I don't 
have to worry about complications like the above.  I've probably even 
used them in an assignment statement. ;)

STeVe
0
9/13/2005 10:24:58 PM
On Mon, 12 Sep 2005 12:52:52 +0200, gabor <gabor@nekomancer.net> wrote:
> hi,
>
> there are 2 versions of a simple code.
> which is preferred?

I don't know. Who cares?

> ===
> try:
> 	text = line[n]
> except IndexError:
> 	text = 'nothing'
> ===
>
>
> which is the one you would use?

The 'try' version. But I'd also ask myself how I could end up in a state where
this part of the code is asked to find a string that doesn't exist, and if I
really want it to keep running, with a made-up value.

/Jorgen

-- 
  // Jorgen Grahn <jgrahn@       Ph'nglui mglw'nafh Cthulhu
\X/                algonet.se>   R'lyeh wgah'nagl fhtagn!
0
jgrahn-nntq (147)
9/17/2005 9:57:30 PM
Reply:

Similar Artilces:

'is not' or '!='
A newbie question to you; what is the difference between statements like: if x is not None: and if x != None: Without any context, which one should be preferred? IMHO, the latter is more readable. On 2014-08-18 21:35, ElChino wrote: > A newbie question to you; what is the difference between statements > like: > if x is not None: > and > if x != None: > > Without any context, which one should be preferred? > IMHO, the latter is more readable. > "x == y" tells you whether x and y refer to objects that are equal. "x is y&qu...

'^=' and '~='?
Hello, What is the difference between '^=' and '~='? Thanks, Duckhye ...

'''''''''''''The Running Update/Append Queries Using VBA code Ordeal''''''''''''''
Hello fellow programmers, I am trying to run an append/update query from code, a command button on a form initiates the queries. the format i am using is; _____________________________________________________ SELECT "criteria" FROM "criteria" WHERE "criteria" UPDATE/APPEND "field selections" RecordSource "qryExample" = above text strings" _______________________________________________________________________ When i am running a SELECT query in this manner it works fine with no problems, and accepts the values of specified linked for...

Python 'for' as Scheme 'let'
We show that the 'for' operator of Python quite unexpectedly can be represented by a 'let' form of Scheme. What looks in Python like for k in range(1,4): print k looks in Scheme as (breset r (let ((k (range r 1 4))) (display k) (newline) )) This iteration construct uncannily resembles Python. It nests and supports the premature termination and skipping of iterations at any level. We should also emphasize that no intermediate lists are constructed! The 'let' in the above code is the ordinary Scheme let. The macro range has been described in the arti...

'''''''''''''The Running Update/Append Queries Using VBA code Ordeal'''''''''''''' #2
Hi, Thanks for ur help there HJ. I know how to do the tasks you specified there. I would like for the update query to use field values from some of the fields on the form (frmInvoices) such as InvoiceNumber, DateFrom, DateTo. My problem is that an append/update query can't find the values in the open Form (frmInvoices) when I specify them as; [Forms]![frmInvoices]![InvoiceNumber] a select query has no problem finding the field values on a form. please help. Aaron Hi Aaron, Could you post the entire code that you are having trouble with? Now it is not possible to see what goes wron...

if str_mo not in ('','.') and str_da not in ('','.') and str_yy not in ('','.') Any shorter ?
Hi, there. =20 I'm just curious if it ever dawned on anybody how to abbreviate this line : if str_mo not in ('','.') and str_da not in ('','.') and str_yy not in ('','.')=20 =20 Igor Kurbeko Clinical Programmer Analyst 678 336 4328 ikurbeko@atherogenics.com =20 no brain no pain =20 how about: if not (str_mo in ('','.') or str_da in ('','.') or str_yy in ('','.')) OR if not (missing(str_mo) or missing(str_da) or missing(str_yy)) Eric On 22 Oct 03 21:13:37 GMT, ikurbeko@ATHER...

A function with 'and' , 'not' , 'null' , 'car' and 'cdr'
What's this ? (defun enigma (x) (and (not (null x)) (or (null (car x)) (enigma (cdr x))))) "I suppose I should learn Lisp, but it seems so foreign." - Paul Graham, Nov 1983 On Wed, Oct 07 2015, CAI GENGYANG wrote: > What's this ? > > > (defun enigma (x) > (and (not (null x)) > (or (null (car x)) > (enigma (cdr x))))) Bad taste? It returns T if the list X contains nil as an element. It would be clearer to write (some #'null x). Helmut CAI GENGYANG ...

Re: if str_mo not in ('','.') and str_da not in ('','.') and str_yy not in ('','.') Any shorter ?
OR you could use ARRAY data new; set old; array igor $ (*) str_mo str_da str_yr; do over igor; if igor ~in (' ','.') then do; end; run; Prasad Ravi Igor Kurbeko <ikurbeko@ATHEROGENIC To: SAS-L@LISTSERV.UGA.EDU S.COM> cc: Sent by: "SAS(r) Subject: if str_mo not in ('','.') and str_da not in ('','.') and str_yy ...

error: expected '=', ',', ';', 'asm' or '__attrib
Hi I'm trying to compile an ADC Driver & come acrosss the following error. I've no experience writing drivers before, and hence have no clue how to fix it. Hope someone out there has encountered the problem & suggesst a fix for the same. The Error is I get is : qadc.c: At top level: qadc.c:97: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'qadc_read' make: *** [qadc.o] Error 1 [root@localhost qadc]# ########################################################################### ADC Driver Code ####################...

error: expected '=', ',', ';', 'asm' or '__attrib
Hi I'm trying to compile an ADC Driver & come acrosss the following error. I've no experience writing drivers before, and hence have no clue how to fix it. Hope someone out there has encountered the problem & suggesst a fix for the same. The Error is I get is : qadc.c: At top level: qadc.c:97: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'qadc_read' make: *** [qadc.o] Error 1 [root@localhost qadc]# ########################################################################### ADC Driver Code ##...

replacement for '{' and '}' ?
I am still playing around with what kind of syntax I would like to mark up my documents. Are there equivalent long substitutes for { and } when they are not used to describe arguments to functions? Something like \begin{group} and \end{group}. In other words, if I could force myself to write, say, \begin{group} \it ... \end{group} instead of {\it ... }, then I believe I could identify from the markup context what is an argument that belongs to a just invoked macro and what is text. {Of course, in this context, \textit{...} would be better.} No more ambiguity whether a in \myfunction{a} i...

Re: '^=' and '~='?
Duckhye, According to the doc ( http://xrl.us/befwjx ) they, and one other set of characters, and the mnemonic 'NE' all represent 'NOT EQUAL'. Art ------- On Wed, 11 Feb 2009 16:52:40 -0600, Duck-Hye Yang <dyang@CHAPINHALL.ORG> wrote: >Hello, >What is the difference between '^=' and '~='? > >Thanks, >Duckhye ...

Replacing ',' with '.'
Hello, I have a huge amount of numbers in a .txt file. The numbers are in the form 2,43252e+1. I need to replace the , with . How should I do this? I'd prefer some import method that does this during the import procedure. -Janne Hi, I guess you import the data as text and convert it then to numbers. Try 'strrep' before you convert the text to numbers. Tobias Jake the Snake schrieb: > Hello, > > I have a huge amount of numbers in a .txt file. The numbers are in the form 2,43252e+1. I need to replace the , with . How should I do this? I'd prefer some import method...

replacing '/' with '\\'
I have a MKS ksh shell script running on a Windows box. In some scripts I have to convert a UNIX filename into a DOS filename, that is replace the '/' with '\\'. For example, replace /opt/siips/archive/text.dat with \\opt\\siips\\archive\\text.dat. I've tried using sed like $FILE='echo $FILE|sed "s/\//\\\/g"' which got me \opt\siips\archive\text.dat. It's close but I still need the second \. Does anyone have any suggestion? Or tell me where I've gone wrong? Thanks -- Steffen On 9 Dec 2004 20:14:21 -0800, sajohn52@yahoo.com <sajohn52@yahoo....

Web resources about - which is more 'pythonic' / 'better' ? - comp.lang.python

Resources last updated: 2/3/2016 3:55:40 PM