Ignore python multiple return value

Say I have a Python function that returns multiple values in a tuple:

def func(): return 1, 2

Is there a nice way to ignore one of the results rather than just assigning to a temporary variable? Say if I was only interested in the first value, is there a better way than this:

x, temp = func()
2

12 Answers

You can use x = func()[0] to return the first value, x = func()[1] to return the second, and so on.

If you want to get multiple values at a time, use something like x, y = func()[2:4].

18

One common convention is to use a "_" as a variable name for the elements of the tuple you wish to ignore. For instance:

def f(): return 1, 2, 3
_, _, x = f()
20

If you're using Python 3, you can you use the star before a variable (on the left side of an assignment) to have it be a list in unpacking.

# Example 1: a is 1 and b is [2, 3]
a, *b = [1, 2, 3]
# Example 2: a is 1, b is [2, 3], and c is 4
a, *b, c = [1, 2, 3, 4]
# Example 3: b is [1, 2] and c is 3
*b, c = [1, 2, 3]
# Example 4: a is 1 and b is []
a, *b = [1]
1

The common practice is to use the dummy variable _ (single underscore), as many have indicated here before.

However, to avoid collisions with other uses of that variable name (see this response) it might be a better practice to use __ (double underscore) instead as a throwaway variable, as pointed by ncoghlan. E.g.:

x, __ = func()
1

Remember, when you return more than one item, you're really returning a tuple. So you can do things like this:

def func(): return 1, 2
print func()[0] # prints 1
print func()[1] # prints 2
1

The best solution probably is to name things instead of returning meaningless tuples (unless there is some logic behind the order of the returned items). You can for example use a dictionary:

def func(): return {'lat': 1, 'lng': 2}
latitude = func()['lat']

You could even use namedtuple if you want to add extra information about what you are returning (it's not just a dictionary, it's a pair of coordinates):

from collections import namedtuple
Coordinates = namedtuple('Coordinates', ['lat', 'lng'])
def func(): return Coordinates(lat=1, lng=2)
latitude = func().lat

If the objects within your dictionary/tuple are strongly tied together then it may be a good idea to even define a class for it. That way you'll also be able to define more complex operations. A natural question that follows is: When should I be using classes in Python?

Most recent versions of python (≥ 3.7) have dataclasses which you can use to define classes with very few lines of code:

from dataclasses import dataclass
@dataclass
class Coordinates: lat: float = 0 lng: float = 0
def func(): return Coordinates(lat=1, lng=2)
latitude = func().lat

The primary advantage of dataclasses over namedtuple is that its easier to extend, but there are other differences. Note that by default, dataclasses are mutable, but you can use @dataclass(frozen=True) instead of @dataclass to force them being immutable.

Here is a video that might help you pick the right data class for your use case. And a another video on attrs vs. dataclass that enlight some interesting details about why attrs might be interesting.

1

Three simple choices.

Obvious

x, _ = func()
x, junk = func()

Hideous

x = func()[0]

And there are ways to do this with a decorator.

def val0( aFunc ): def pick0( *args, **kw ): return aFunc(*args,**kw)[0] return pick0
func0= val0(func)
4

This seems like the best choice to me:

val1, val2, ignored1, ignored2 = some_function()

It's not cryptic or ugly (like the func()[index] method), and clearly states your purpose.

1

This is not a direct answer to the question. Rather it answers this question: "How do I choose a specific function output from many possible options?".

If you are able to write the function (ie, it is not in a library you cannot modify), then add an input argument that indicates what you want out of the function. Make it a named argument with a default value so in the "common case" you don't even have to specify it.

 def fancy_function( arg1, arg2, return_type=1 ): ret_val = None if( 1 == return_type ): ret_val = arg1 + arg2 elif( 2 == return_type ): ret_val = [ arg1, arg2, arg1 * arg2 ] else: ret_val = ( arg1, arg2, arg1 + arg2, arg1 * arg2 ) return( ret_val )

This method gives the function "advanced warning" regarding the desired output. Consequently it can skip unneeded processing and only do the work necessary to get your desired output. Also because Python does dynamic typing, the return type can change. Notice how the example returns a scalar, a list or a tuple... whatever you like!

If this is a function that you use all the time but always discard the second argument, I would argue that it is less messy to create an alias for the function without the second return value using lambda.

def func(): return 1, 2
func_ = lambda: func()[0]
func_() # Prints 1 

When you have many output from a function and you don't want to call it multiple times, I think the clearest way for selecting the results would be :

results = fct()
a,b = [results[i] for i in list_of_index]

As a minimum working example, also demonstrating that the function is called only once :

def fct(a): b=a*2 c=a+2 d=a+b e=b*2 f=a*a print("fct called") return[a,b,c,d,e,f]
results=fct(3)
> fct called
x,y = [results[i] for i in [1,4]]

And the values are as expected :

results
> [3,6,5,9,12,9]
x
> 6
y
> 12

For convenience, Python list indexes can also be used :

x,y = [results[i] for i in [0,-2]]

Returns : a = 3 and b = 12

It is possible to ignore every variable except the first with less syntax if you like. If we take your example,

# The function you are calling.
def func(): return 1, 2
# You seem to only be interested in the first output.
x, temp = func()

I have found the following to works,

x, *_ = func()

This approach "unpacks" with * all other variables into a "throwaway" variable _. This has the benefit of assigning the one variable you want and ignoring all variables behind it.

However, in many cases you may want an output that is not the first output of the function. In these cases, it is probably best to indicate this by using the func()[i] where i is the index location of the output you desire. In your case,

# i == 0 because of zero-index.
x = func()[0]

As a side note, if you want to get fancy in Python 3, you could do something like this,

# This works the other way around.
*_, y = func()

Your function only outputs two potential variables, so this does not look too powerful until you have a case like this,

def func(): return 1, 2, 3, 4
# I only want the first and last.
x, *_, d = func()

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like