Dirty_Fox
Dirty_Fox

Reputation: 1751

In python should I use try or If and why?

First of all, I know the difference between if and try and I am perfectly aware that their purposes are completely different -while one makes tests, the other manages errors. However, in this particular case, is it better to use if or try ?

#option1
def getListRank(self):
    for point in self.soup.findAll('td',class_="rank-cell"):
        p = (point.get_text().replace('\t','').replace('\n','')
                             .replace('\r','').replace(',',''))
        if 'T' in p:
            self.listRk.append(int(p.replace('T',''))
        else:
            self.listRk.append(int(p))
    return self.listRk 

I am very tempted to use the following option2, given the fact that I know that the only reason that could prevent from turning p into an integer is the presence of that 'T'. Therefore, would it be unusual or less efficient to write this :

#option2
def getListRank(self):
    for point in self.soup.findAll('td',class_="rank-cell"):
        p = (point.get_text().replace('\t','').replace('\n','')
                             .replace('\r','').replace(',',''))
        try:
            self.listRk.append(int(p))
        except:
            self.listRk.append(int(p.replace('T',''))                
    return self.listRk

I ask the questions because I read this before so I assume that it is "pythonic". However if there is a piece of explanation/convention I am more than interested.

Thanks in advance

Upvotes: 1

Views: 182

Answers (2)

chepner
chepner

Reputation: 531135

Don't use either. Remove T along with the other characters, as @tobias_k suggested; then you know that int(p) will succeed. You can do this more easily using re.sub as well, simplifying this enough to use a list comprehension instead of a for loop.

import re

to_replace = re.compile(r'\t|\n|\r|T|,')
def getListRank(self):
    points = self.soup.findAll('td', class_="rank-cell")

    self.listRk = [int(re.sub(to_replace, "", p.get_text())) for p in points]
    return self.listRk

You can also use str.translate to remove your set of characters.

self.listRk = [int(p.get_text().translate(None, "\r\n\tT,")) for p in points]

Upvotes: 2

ShadowRanger
ShadowRanger

Reputation: 155363

At least in CPython's interpreter, exceptions really don't cost much more, and are sometimes cheaper, particularly if the test would require more Python level code, while the exception would be raised implicitly by a C layer function.

The reason to choose if checks over exceptions is usually a matter of style; save exceptions for actual exceptional cases, not as a generic control flow mechanism. That said, Python is all about EAFP, so it tends to use exceptions for less exceptional purposes.

Just please, for the love of god, don't use bare except blocks. Catch the exception you expect, and no more, because otherwise you'll catch stuff that should never have been caught, e.g. if you typo append as apend, the AttributeError will be caught.

Of course, in your particular case, you could just skip the test completely.

self.listRk.append(int(p.replace('T',''))

works whether or not a T is in your string after all. Checking for it is pointless, just get rid of it if it's there and convert to int.

Upvotes: 0

Related Questions