Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning intermediate results from function in Python

Imagine I've got a Python module with some function in it:

def sumvars(x, y, z):
    s = x
    s += y
    s += z
    return s

But sometimes I want to get results of some intermediate calculations (for example, I could have a function which reverses a matrix and would like to know the determinant which has been calculated as an intermediate step as well). Obviously, I wouldn't want to redo those calculations again if they were already done within that function.

My first idea is to return a dict:

def sumvars(x, y, z):
    d = {}
    s = x
    d['first_step'] = s
    s += y
    d['second_step'] = s
    s += z
    d['final'] = s
    return d

But I don't recall any functions in numpy or scipy which return dicts and so it seems like this might be not a good idea. (Why?) Also routinely I'll always have to type sumvars(x,y,z)['final'] for a default return value...

Another option I see is creating global variables but seems wrong having a bunch of them in my module, I would need to remember their names and in addition not being attached to the function itself looks like a bad design choice.

What would be the proper function design for such situation?

like image 360
sashkello Avatar asked Feb 26 '14 06:02

sashkello


People also ask

How do you return a value from a function in Python?

The Python return statement is a special statement that you can use inside a function or method to send the function's result back to the caller. A return statement consists of the return keyword followed by an optional return value. The return value of a Python function can be any Python object.

Can we return list from function in Python?

Any object, even a list, can be returned by a Python function. Create the list object within the function body, assign it to a variable, and then use the keyword "return" to return the list to the function's caller.

How do you return multiple values from a function in Python?

To return multiple values from a function in Python, return a tuple of values. A tuple is a group of comma-separated values. You can create a tuple with or without parenthesis. To access/store the multiple values returned by a function, use tuple destructuring.


2 Answers

Generally when you have two different ways you want to return data, go ahead and make two different functions. "Flat is better than nested", after all. Just have one call the other so that you Don't Repeat Yourself.

For example, in the standard library, urllib.parse has parse_qs (which returns a dict) and parse_qsl (which returns a list). parse_qs just then calls the other:

def parse_qs(...):

    parsed_result = {}
    pairs = parse_qsl(qs, keep_blank_values, strict_parsing,
                      encoding=encoding, errors=errors)
    for name, value in pairs:
        if name in parsed_result:
            parsed_result[name].append(value)
        else:
            parsed_result[name] = [value]
    return parsed_result

Pretty straightforward. So in your example it seems fine to have

def sumvars(x, y, z):
    return sumvars_with_intermediates(x, y, z).final

def sumvars_with_intermediates(x, y, z):
    ...
    return my_namedtuple(final, first_step, second_step)

(I favor returning namedtuples instead of dicts from my APIs, it's just prettier)

Another obvious example is in re: re.findall is its own function, not some configuration flag to search.

Now, the standard library is a sprawling thing made by many authors, so you'll find counterexamples to every example. You'll far more often see the above pattern rather than one omnibus function that accepts some configuration flags, though, and I find it far more readable.

like image 136
roippi Avatar answered Sep 21 '22 01:09

roippi


Put the common calculation into its own function as Jayanth Koushik recommended if that calculation can be named appropriately. If you want to return many values (an intermediate result and a final result) from a single function then a dict may be an overkill depending on what is your goal but in python it is much more natural to simply return a tuple if your function has many values to return:

def myfunc():
    intermediate = 5
    result = 6
    return intermediate, result

# using the function:
intermediate, result = myfunc()
like image 29
pasztorpisti Avatar answered Sep 18 '22 01:09

pasztorpisti