A return statement can return multiple values.


Functions can return multiple values


Functions can only return one value

Here is what's right.

Functions can have multiple parameters, but can only return one single value.

In the diagram above, this is represented by a box (the function) potentially having multiple incoming arrows on the left (the parameters) but only one outgoing arrow on the right (the return value).

Python allows to specify “a list of expressions”, separated by commas, in many places. The return statement is one such place: a statement like return v1, v2 is perfectly legal. That does not mean that we are returning two values!

The “list of expressions” gets evaluated to a tuple, whose components are the result of the evaluation of the individual comma-separated expressions. Despite being created without using parentheses explicitly, the single value that gets returned is still a tuple.

We can observe this by storing the returned value in a variable and then accessing the components of the tuple:

def new_key_pair():
    # generates new public and private key
    # pub = ...
    # priv = ...
    return pub, priv

pair = new_key_pair()
print(pair[0])  # prints the public key
print(pair[1])  # prints the private key
print(pair)     # prints the tuple

Where could this misconception come from?

There are certain cases in which one would like to return multiple values. But given that we can only return one value from a function, the usual strategy is to group multiple values in some kind of data structure (e.g., a tuple or an object) and return that structure.

Python allows creating tuple with a particularly lightweight syntax. Seeing code like this may lead to believe that functions like new_key_pair return two values.

def new_key_pair():
    # ... 
    return pub, priv 

k_pub, k_priv = new_key_pair()

Combined with the ability to have multiple targets on the left-hand side of an assignment statement, this fragment of code may induce to believe that it is indeed possible to return multiple values. In reality, the function is just returning a tuple with two components. The values of the individual components get then assigned to the two names specified on the left-hand side of the assignment.

How can you build on this misconception?

It might be instructive to annotate the type of the return value for functions that return a tuple without the explicit use of parentheses:

def new_key_pair() -> tuple[int, int]:
    # ...
    return pub, priv 

This misconception can also serve as a good example of different concrete syntax that correspond to the same language construct. The following expressions all evaluate to a tuple containing the numbers 1 and 2.

1, 2     # evaluates to (1, 2)
(1, 2)   # evaluates to (1, 2)
(1, 2,)  # evaluates to (1, 2)

Stay up-to-date

Follow us on  twitter to hear about new misconceptions.