Is there a better way to write this code in python?
result = slow_function()
if result:
return result
[...]
The function slow_function
can return a value or None
and it's slow, so this is not feasible:
if slow_function():
return slow_function()
There is nothing wrong with the first way, but using a temporary variable seems overkill for python.
This code is pretty useful when you are solving a problem using recursive calls over f
and with local assumption, for example you select an item from a list and then check if there is a feasible solution, otherwise you have to choose another one. Something like:
def f(n):
for x in xrange(n):
result = slow_function(x):
if result:
return result
[...]
Wouldn't it be better something more idiomatic like:
def f(n):
for x in xrange(n):
return slow_function(x) if is not None
This can be extended to check any kind of value. It would be an easy-to-read return if statement.
Additional example for code lovers
Imagine you have a list of lists of numbers:
lists = [[1,2,3],[4,5],[6,7,8],[9,10],...]
and you want to select one item for each list such that there is at most one even number in the selection. There could be a lot of lists, so trying each combination would be wasteful since you can already tell that if you start selecting [1,2,4,...] there could be no feasible solutions.
def check(selected):
even_numbers = filter(lambda n: (n % 2) == 0, selected)
return len(even_numbers) < 2
def f(lists, selected=[]):
if not lists:
return selected
for n in lists[0]:
if check(selected + [n]):
result = f(lists[1:], selected + [n])
if result:
return result
Wouldn't it be better a syntax like:
def f(lists, selected=[]):
return selected if not lists
for n in lists[0]:
if check(selected + [n]):
return f(lists[1:], selected + [n]) if is not None
The best I've done so far is to turn the function in a generator of feasible solutions:
def f(lists, selected=[]):
if not lists:
yield selected
else:
for n in lists[0]:
if check(selected + [n]):
for solution in f(lists[1:], selected + [n]):
yield solution