Reputation: 638
I want to return a value depending on which among a set of functions returns true.
if a():
return 'a'
elif b():
return 'b'
else:
return 'c'
is there a more pythonic way of doing so?
Upvotes: 3
Views: 1118
Reputation: 6655
Actually a rather pythonic and generalizable way to do what you ask is probably
next((f for f in [a,b] if f()), c).__name__
Note that the callable c
(defined on purpose) is used as default if the generator is empty.
Upvotes: -1
Reputation: 777
If you can put all of the functions into an iterable:
functions = [a, b]
for func in functions:
if func():
return func.__name__
return "c"
This makes more sense when supplied with lots of functions, as the only thing that changes is functions
(and optionally a 'default' return value). If you want this as a function:
def return_truthy_function_name(*functions, default):
"""Iterate over `*functions` until a function returns a truthy value, then return its name.
If none of the functions return a truthy value, return `default`.
"""
for function in functions:
if function():
return function.__name__
return default
Upvotes: 4
Reputation: 140178
I don't know if it's more pythonic, but it's shorter using 2 nested ternary expressions:
return 'a' if a() else ('b' if b() else 'c')
if there are more than 2 conditions, nesting ternary expressions becomes ludicrious and the loop approach of Coal_ answer (maybe using a list of tuples
to associate the function call and the return value if there's no obvious relation between the 2) is better.
Upvotes: 3
Reputation: 453
d = {a: 'a() is true',
b: 'b() is true',
c: 'c() is true'}
for func, answer in d.items():
if func():
return answer
return 'nothing seems to be true'
Upvotes: 0
Reputation: 1307
You could use a conditional expression:
return 'a' if a() else 'b' if b() else 'c'
Upvotes: 1