2

I have a function called crawl which will return a link to a website. Then I do something like:

found.append(crawl()) (found is a list)

This works fine as long as crawl returns a valid link, but sometimes it does not return anything. So a value of None gets added to the list.

So my question is that, is it possible to return something from crawl that will not not add anything to the list?

xrisk
  • 3,790
  • 22
  • 45
  • 4
    As a footnote, this sounds like a terrible question. – xrisk Jun 21 '15 at 14:10
  • 5
    No, it's not possible simply because `None` *is* nothing. The best you can do is `retval = crawl(); if retval: found.append(retval)`. – vaultah Jun 21 '15 at 14:11
  • 1
    Although technically you have to return something, even if it is `None`, I disagree that for *practical* purposes checking for `None` is not the only possibility. Raising an exception rather than returning `None` is a very reasonable thing to do when a problem is encountered by a function that a list is being built from. If the condition causing `return None` or an exception is uncommon, exception handling can have better performance than checking for `None`. – Eric Appelt Jun 21 '15 at 15:07

4 Answers4

10

In Python nothing is something: None. You have to use if-condition:

link = crawl()
if link is not None:
    found.append(link)

or let crawl return a list, which can contain one or zero elements:

found.extend(crawl())
Dan D.
  • 73,243
  • 15
  • 104
  • 123
Daniel
  • 42,087
  • 4
  • 55
  • 81
2

What you could do is to pass the list in to the crawl function and if there is anything to add append it otherwise not. Something like:

def crawl(found):
   """ Add results to found list """
   # do your stuff saving to result
   if result is not None:
       found.append(result)

# Call this as 
   crawl(found)
Steve Barnes
  • 27,618
  • 6
  • 63
  • 73
1

This is not possible directly.

You can test for a None being returned though, using the following code.

returned_link = crawl()
if returned_link is not None:
    found.append(returned_link)
Jay Bosamiya
  • 3,011
  • 2
  • 14
  • 33
  • 3
    `if returned_link:` might wrongly skip an append if `crawl` can return, eg, the empty string. If you want to test for `None`, it's better to be explicit: `if returned_link is not None:` – lvc Jun 21 '15 at 14:20
  • @lvc, thanks for that. Didn't realize that empty strings would affect the condition. Edited the answer to reflect the suggestion. – Jay Bosamiya Jun 21 '15 at 14:23
1

If a function returns it has to return an object, even if that object is None. However, there is another answer being overlooked, and that is to raise an exception rather than returning None.

As other people point out, one approach is to check if the returned object is None before appending it to the list:

link = crawl()
if link is not None:
    found.append(link)

The other approach is to define some exception, perhaps WebsiteNotFoundError, and have crawl execute raise WebsiteNotFoundError instead of return None. Then you can write:

try:
    found.append(crawl())
except WebsiteNotFoundError:
    pass  # or take appropriate action

The advantage of the exception handling approach is that it is generally faster than checking for None if returning None is a relatively rare occurrence compared to returning a valid link. Depending on the use, it may be more readable in the sense that the code naturally explains what is going wrong with the function.

Eric Appelt
  • 2,843
  • 15
  • 20