Nijan
Nijan

Reputation: 638

Pythonic way of returning a value depending of results of multiple functions

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

Answers (5)

keepAlive
keepAlive

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

Daniel
Daniel

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

Jean-François Fabre
Jean-François Fabre

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

Grisha
Grisha

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

Galen
Galen

Reputation: 1307

You could use a conditional expression:

return 'a' if a() else 'b' if b() else 'c'

Upvotes: 1

Related Questions