Search code examples
pythoncoding-stylereturn-valuecalling-convention

Pythonic way to efficiently handle variable number of return args


So I have a function that can either work quietly or verbosely. In quiet mode it produces an output. In verbose mode it also saves intermediate calculations to a list, though doing so takes extra computation in itself.

Before you ask, yes, this is an identified bottleneck for optimization, and the verbose output is rarely needed so that's fine.

So the question is, what's the most pythonic way to efficiently handle a function which may or may not return a second value? I suspect a pythonic way would be named tuples or dictionary output, e.g.

def f(x,verbose=False):
    result = 0
    verbosity = []
    for _ in x:
        foo = # something quick to calculate
        result += foo
        if verbose:
            verbosity += # something slow to calculate based on foo
    return {"result":result, "verbosity":verbosity}

But that requires constructing a dict when it's not needed.

Some alternatives are:

# "verbose" changes syntax of return value, yuck!
return result if verbose else (result,verbosity)

or using a mutable argument

def f(x,verbosity=None):
    if verbosity:
        assert verbosity==[[]]
    result = 0
    for _ in x:
        foo = # something quick to calculate
        result += foo
        if verbosity:
            # hard coded value, yuck
            verbosity[0] += # something slow to calculate based on foo
    return result

# for verbose results call as
verbosity = [[]]
f(x,verbosity)

Any better ideas?


Solution

  • Don't return verbosity. Make it an optional function argument, passed in by the caller, mutated in the function if not empty.

    The non-pythonic part of some answers is the need to test the structure of the return value. Passing mutable arguments for optional processing avoids this ugliness.