How to return result of function?

In Python, is there a clean way to return the result of a function if it's not None?

  • Is there a clean way to make the following snippet a one-liner? ans = call_function() if ans: return ans ...

  • Answer:

    You might be able to shorten this pattern using a generator function.  Rewrite def foo(): ans = bar() if ans is not None: return ans ans = baz() if ans is not None: return ans … print foo() as def foo(): yield bar() yield baz() … print next(ans for ans in foo() if ans is not None)

Anders Kaseorg at Quora Visit the source

Was this solution helpful to you?

Other answers

Personally I'd suggest focusing more on the semantics of your code rather than fixating on reducing one or two lines here or there. It's for more important to understand the difference between: if foo: return foo ... and the similar but significantly different: if foo is not None: return foo In the latter case you only return if foo was a reference to the None object (a specific, singleton value which happens to evaluate to False in conditional statements and is frequently used as a sentinel value, similar to nil in Lisp, undef in Perl, and the null pointer in C).  In the former example we return if foo is any non-false value (any non-zero numeric, non-empty string, list, tuple, dictionary, or other container, even a reference to an instance, class, or other object. The point is to be cognizant of the difference between using something like None as a sentinel value and simply evaluating the truth or falsity of an object/reference.  (BTW: if you need to create a sentinel such that you can distinguish between it and some None instance then you can just use sentinel = object() to create an object which will fail for any if foo is ... tests unless that foo is a reference to your particular sentinel instance.  This is a subtle and rarely necessary distinction; but useful to understand, nonetheless). Regarding your specific question: It sounds like you want to assign a result and use the assignment as an expression in the same line of code.  (C and Perl and probably some others support this). In Python "variable assignments" (technically the binding of values to names) are statements rather than expressions.  I seem to recall reading that this was a deliberate decision by Guido von Rossum intending to make one of the most common C (and Perl and ...) programming errors impossible in Python: [code c] if (foo=bar) { do_something();}  /* Ooops, meant to use == instead of just = */ [/code] If that's really your intention here then there is no elegant way to return your code example from three lines down to just one. You can, of course, reduce your code example to just two lines: ans = call_function() if ans is not None: return ans # continue with other code in current function As others are pointing out there are other things you can do if you call a whole series of functions and return the first result that's non-false or that's not None Because functions are first order objects in Python you can assign functions to dictionaries and append them to lists and generally treat them like you might with other data.  Thus you could do something like: trials = [call_foo, call_bar, call_bang] # ... for each_func in trials: result = each_func(*args) if attempt is not None: return result (Obviously all of the functions in our list have to support compatible argument call signatures). A similar concept is used in dispatch tables.  You can assign function references to keys in a dictionary and then dispatch calls to those functions with something like: dispatch = { 'foo': do_foo, 'bar': do_bar, ... } for line in input: dispatch[line.split()[0]](line) # or better: dispatch.get(line.split()[0], do_default)(line) # to handle any lines with unrecognized keys. ... to process a series of lines to functions based on the first "word" on each line, for example. This dispatch technique is recommended when people are asking about "case" or "switch" statements or asking for an alternative to long sequences of elif clauses.

Jim Dennis

Presumably you're asking because you have a number of these in the function. In that case you might try: class MyException: pass def error(): raise MyException() try: None if call_function() else error() except MyException: pass if you need to use the value you might be able to do something nasty like: ans = [x if x else error() for x in [call_function()]][0]. I'd also probably recommend adding a msg parameter to error.

Colin Barrett

You can achieve exactly the effect you want with the right decorators (based on the use of exceptions as suggested). (I've edited my initial answer to use decorators, to eliminate boilerplate in user-code). Here's how: class ReturnException(Exception): def __init__(self, val): self.val = val pass def return_if_not_none(val): if val is not None: raise ReturnException(val) def return_handler(f): '''decorator''' def wrapper(*args, **kwargs): try: val = f(*args, **kwargs) except ReturnException as e: return e.val else: return val return wrapper # # foo(), bar(), and baz() are examples of call_function() in original # poster's question: # def foo(): return None def bar(): return "I'm not None!" def baz(): return None # This is the function where we want to have one-liner return's of non-None's # You can have arbitrary code between the one-liners. @return_handler def some_func(): return_if_not_none(foo()) # ...other code... return_if_not_none(bar()) # ...other code... return_if_not_none(baz()) # ...other code... return "Everybody was None!" def other_func(): print(some_func()) # Let's try it: if __name__ == '__main__': other_func() # here's what happens: # >>> other_func() # I'm not None! # >>>

Taher Haveliwala

Another option to handle this: def _test1(arg): return ... def _test2(arg): return ... def _test3(arg): return ... def tester(arg): return _test1(arg) or _test2(arg) or _test3(arg) This approach will allow you to unit test each component individually, then test the whole flow separately.  This would make for cleaner (and easier to diagnose) unit tests and failures.

Rob Roland

The best way I can see to make it work is something like: return call_function() or do_something() where do_something() would be a function that does whatever was supposed to happen after the above code snippet. Anyway it seems to be a case where trying to make something very simple far more complicated than it should be. If you absolutely have to make your code shorter you may try ans = call_function() if ans: return ans and if call_function() has no side-effects and isn't computationally intensive then if call_function(): return call_function() might work (and perhaps can be made a bit more memory efficient by using a generator...

Michael Genkin

Related Q & A:

Just Added Q & A:

Find solution

For every problem there is a solution! Proved by Solucija.

  • Got an issue and looking for advice?

  • Ask Solucija to search every corner of the Web for help.

  • Get workable solutions and helpful tips in a moment.

Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.