2

I am parsing HTML table with BeautifulSoup like this:

for tr in table_body.find_all('tr'):      
            for td in tr:  
                if td.text == 'Description':
                    description = td.find_next('td').text
                if td.text == 'Category':
                    category = td.find_next('td').text                             
                if td.text == 'Department':
                    department = td.find_next('td').text                             
                if td.text == 'Justification':
                    justification = td.find_next('td').text
print(description, category, department, justification)

I refactored the multiple if statements into a function:

def html_check(td, text):
        if td.text == text:
            value = td.find_next('td').text
            return value

that is called like this:

for tr in table_body.find_all('tr'):      
            for td in tr:  
                description= html_check(td, 'Description')
                category = html_check(td, 'Category')
                department = html_check(td, 'Department')
                justification = html_check(td, 'Justification')
print(description, category, department, justification)

My problem is that when the function html_check will not find a match, it will return None, which will be printed. This is not desirable.

Is there any way to make this function return a value only when the if condition in it is met?

micstr
  • 5,080
  • 8
  • 48
  • 76
barciewicz
  • 3,511
  • 6
  • 32
  • 72
  • 2
    What should happen when the condition is not met? Return an empty string? If so - just add `return ""` at the end of your function, outside of the `if` condition. If you don't return anything from your function explicitly, `None` will be returned. – zwer Jul 24 '18 at 12:20
  • `None` returned from a function isn't automatically printed. Just use another `if` check to see if the function returns `None` and only `print()` when it returns something other than `None`. – roganjosh Jul 24 '18 at 12:22
  • "Is there any way to make this function return a value only when the if condition in it is met?" No. Python will have the function return `None` if you don't specify a return value for the given input. – John Coleman Jul 24 '18 at 12:23
  • When the condition is not met, I want the function to behave alsmost like it was never called - so to return nothing, not even `None` – barciewicz Jul 24 '18 at 12:23
  • 1
    Python doesn't work like that. You can *ignore* the `None`, but you can't prevent the interpreter from returning it. Just call the function conditionally. – John Coleman Jul 24 '18 at 12:24

5 Answers5

8

Python will always return None, if no return is specified at the point of exiting the function call. Your options are:

  • return something else if the condition is not met.
  • ignore the function if it returns None

option 1 (return something else when the condition isn't met):

 def html_check(td, text):
     if td.text == text:
        value = td.find_next('td').text
        return value
     return "no value found"

option 2 (ignores the function if None is returned):

if html_check(td, 'section'):
     # do things
Christian W.
  • 2,532
  • 1
  • 19
  • 31
2

You can specify a default value, to return, in case no element matches. Something like:

def html_check(td, text):
        if td.text == text:
            value = td.find_next('td').text
            return value
        return "Default Value"

Also, you can spcify the default value via argument, which would somewhat look like :

 def html_check(td, text, default_value):
            if td.text == text:
                value = td.find_next('td').text
                return value
    return default_value

And, then use it like:

for tr in table_body.find_all('tr'):      
            for td in tr:  
                description= html_check(td, 'Description', 'Default Description')
                category = html_check(td, 'Category','Default Category')
                department = html_check(td, 'Department', 'Default Department')
                justification = html_check(td, 'Justification', 'Default Justification')
print(description, category, department, justification)
1

You can try this to print only those whose values match.

for tr in table_body.find_all('tr'): 
            fields = ['Description','Category','Department','Justification']
            for td in tr:
                print (['{}:{}'.format(i,html_check(td,i)) for i in fields if html_check(td,i)])
satyam soni
  • 259
  • 1
  • 9
0

My solution would be

def html_check(td, text):
        if td.text == text:
            value = td.find_next('td').text
            if not value is None:
               return value
            else:
                value ="Not able to find"
                return value

However we can not remove None, if html_check function is not returning anything, in python we init it with None. But for our sake we can bypass and init it with something else dev wants.

TheExorcist
  • 1,966
  • 1
  • 19
  • 25
  • Your solution, as it's currently provided, will still return `None`. You might assign `value = "Not able to find"`, but you don't return it. Which means it still returns `None` – TayTay Jul 24 '18 at 12:35
  • Ohh I forgot to add some line. My code is not optimized, its just an example not more than that, we can optimize the code so that return is called once. – TheExorcist Jul 24 '18 at 12:47
0

Only print if all variables have a value:

print_me = description and category and department and justification
print(description, category, department, justification) if print_me else None
BeRT2me
  • 12,699
  • 2
  • 13
  • 31