Python: Efficiently calling subset variables of multiple returns function

1k Views Asked by At

I wanna know if I can prevent my function to work through all its routine if I'm only interested in one (or less than total) of the variables it returns.

To elucidate, suppose I have a function with (a tuple of) multiple returns:

def func_123(n):
    x=n+1
    y=n+2
    z=n+3
    return x,y,z

If I'm only interested in the third values, I can just do:

_,_,three = func_123(0)

But I wanna know how it works in the function.

Does my function performs of three calculations and only then chooses to 'drop' the first two and give me the one i want or does it recognise it can do a lot less work if it only performs the subroutines needed to return the value i want? If the first, is there a way around this (besides, of course, creating functions for each calculation and let go of an unique function to organize all subroutines)?

4

There are 4 best solutions below

4
On BEST ANSWER

It will calculate, and return, all of the values. For example

def foo(x):
    return x+1, x+2

When I call this function

>>> foo(1)
(2, 3)
>>> _, a = foo(1)
>>> a
3
>>> _
2

Note that _ is a perfectly valid, and usable, variable name. It is just used by convention to imply that you do not wish to use that variable.

The closest thing to what you are describing would be to write your function as a generator. For example

def func_123(n):
    for i in range(1,4):
        yield n + i

>>> a = func_123(1)
>>> next(a)
2
>>> next(a)
3
>>> next(a)
4

In this way, the values are evaluated and returned lazily, or in other words only when they are needed. In this way, you could craft your function so they return in the order that you want.

0
On

It doesn't "choose" or "drop" anything. What you're using is tuple assignment; specifically, you're assigning the return value to the tuple (_,_,three). The _ variable is just a convention for a "throw away" variable.

0
On

It's only a convention to use _ for unused variables.So all the statements in the function do get evaluated.

0
On

I would like to try something differently using functools builtin module (this may not be exactly what you are looking for but you can rethink of what you are doing.)

>>> import functools
>>> def func_123(n, m):
...     return n + m
...
>>> func_dict = dict()
>>> for r in [1,2,3]:
...     func_dict[r] = functools.partial(func_123, r)
...
>>> for k in [1,2,3]:
...     func_dict[k](10)
...
11
12
13
>>> func_dict[3](20)
23
>>>

OR

>>> func_1 = functools.partial(func_123, 1)
>>> func_2 = functools.partial(func_123, 2)
>>> func_3 = functools.partial(func_123, 3)

>>> func_1(5)
6
>>> func_2(5)
7
>>> func_3(5)
8
>>> func_3(3)
6
>>>

So, you don't need to worry about returning output in tuple and selecting the values you want.