4

Say I have 2 functions. I want func2 to return func1 UNLESS func1 returns None, in which case func2 returns something else. There are two ways that I could do this, but they both feel slightly wrong.

I could say:

def func1(n): if (condition): return foo def func2(n): if func1(n) is not None: return func1(n) else: return something_else 

But this feels wrong because I have to call func1(n) twice (and func1(n) is a larger computation). To get around that, I could say:

def func1(n): if (condition): return foo def func2(n): foo = func1(n) if foo is not None: return foo else: return something_else 

but this feels wrong because I don't think I should have to assign a new variable that will never get used again, just to check if func1 returned None.

Is there an easier way to do this where I don't have to call func1 twice and I don't have to create a new variable? If this is the only way, which of the two would you recommend? I currently have it using the second way (Where I set foo to what func1 returned, than return foo unless foo == None)

Also, keep in mind that in my real code, I call several different functions, and I want to return the first one that is not None, this is just a simpler version of code that gets the question across.

4
  • 1
    You should use is and is not instead of == and !=, for singletons like None. So say the docs. stackoverflow.com/questions/2209755/python-operation-vs-is-not Commented Jul 15, 2014 at 19:00
  • Please don't use == True; if condition: is enough and less prone to errors (as comparisons chain, you're likely to produce the wrong expression if you added other comparisons). Commented Jul 15, 2014 at 19:01
  • Also, if you're checking against a type use isinstance Commented Jul 15, 2014 at 19:01
  • Okay, keep in mind that this is not exactly my code, but simpler code I made to show what I was trying to do. Commented Jul 15, 2014 at 19:06

4 Answers 4

9

Since None evaluates to False, you could do:

def func2(n): return func1(n) or something_else 

It should be noted however that this will cause func2 to return something_else if func1(n) returns anything falsey (0, [], etc.)


For many functions, you could use next and some generator expressions:

def myfunc(n): vals = (f(n) for f in (func1, func2, func3...)) return next((v for v in vals if v is not None), something_else) 
Sign up to request clarification or add additional context in comments.

2 Comments

If you need to return something falsey from func1(n), do ret = func1(n); return ret if ret is not None else something_else
Hm, maybe I should have specified this in the question, but I have many different functions, and I want to return the first one that isn't None. I guess I could do return func1(n) or func2(n) or func3(n) or something_else
6

Giving a name to the result of calling func1 is relatively cheap, so I'd do that, but write the function like this:

def func2(n): ret = func1(n) return ret if ret is not None else something_else 

Comments

1

You definitely don't want to call func1 twice - as well as being inefficient, func1 may have side effects or produce a slightly different answer depending on the state at the time.

Also, there is no need for the else after a return as the return exited the function.

A revised version of your second option would be:

def func1(n): if condition: return foo def func2(n): foo = func1(n) if foo is None: return something_else return foo 

Note that this works even if 'func1' returns a falsey value.

Alternatively, noting the content of func1, could you do:

def func1(n): return foo def func2(n): foo = func1(n) if condition: return foo return something_else 

It depends on what the real content of func1 actually is.

2 Comments

I am aware that the else is unnecessary. Also, your revision is basically what my code is now, I am just wondering if it's absolutely needed to create a variable foo. Also, the content of func1 is far too complicated to add the condition into func2, especially seeing as how the condition of func1 calls other functions, and returns the first of those functions that doesn't return None.
I can't think of any way to avoid creating the variable foo if the restrictions of iCodez's answer are a problem.
1

As a completely different take from my previous answer, based on your comment to iCodez:

def func1(n): return ham def func2(n): return jam def func3(n): return spam def mainfunc(n): for f in (func1, func2, func3): foo = f(n) if foo is not None: return foo 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.