How to Return Two Values from a Python Function
by Christoph Schiessl on Python
As a freelance web developer, I have to read a lot of Python code, and sometimes, I see the following pattern to return two values from a function.
def make_hero():
real_name = "Tony Stark"
is_avenger = True
return real_name, is_avenger
It may seem trivial, but it takes some background knowledge to move from an intuitive to a more formalized and solid understanding.
First, the local variables real_name
and is_avenger
have the types str
and bool
, respectively, which follows from how they were initialized with literal values. We can add type hints to make this explicit:
def make_hero():
real_name: str = "Tony Stark"
is_avenger: bool = True
return real_name, is_avenger
Second, the statement return real_name, is_avenger
is equivalent to return (real_name, is_avenger)
because the return
statement is defined to take a so-called expression list.
return_stmt ::= "return" [expression_list]
Expression lists, which have nothing to do with the list
class, are defined in the grammar as comma-separated lists of expressions. Note that a single expression followed by a comma also qualifies ...
expression_list ::= expression ("," expression)* [","]
Depending on where the expression list appeared in the Python code, there are three distinct possibilities for evaluation. The expression list a,b
, consisting of two expressions, a
and b
, is evaluated to ...
- ... an instance of the
set
class if wrapped in curly braces (i.e.,{a,b}
). - ... an instance of the
list
class if wrapped in square brackets (i.e.,[a,b]
). - ... an instance of the
tuple
class if wrapped in parentheses (i.e.,(a,b)
) or without any brackets (i.e.,a,b
).
Clearly, in our case, there are no brackets whatsoever, and therefore, the expression real_name, is_avenger
evaluates to a tuple
. We can add another type annotation to make this explicit:
def make_hero() -> tuple:
real_name: str = "Tony Stark"
is_avenger: bool = True
return real_name, is_avenger
Third, you need to know that tuples have a fixed number of elements that are always identical to the length of the expression list with which they were created. Furthermore, the order of the elements in a tuple
and the order of expressions in the expression list must always be the same.
For our example, the expression list real_name, is_avenger
defines a tuple consisting of a str
and a bool
, which can be written as tuple[str,bool]
in a type annotation.
def make_hero() -> tuple[str, bool]:
real_name: str = "Tony Stark"
is_avenger: bool = True
return real_name, is_avenger
So, there you have it. This is the most straightforward way to return two values from a Python function. The length of tuples and expression lists isn't limited, so you can easily extend this approach to return three or more values.
def make_hero() -> tuple[str, str, bool]:
name: str = "Iron Man"
real_name: str = "Tony Stark"
is_avenger: bool = True
return name, real_name, is_avenger
You have to be careful, though, not to push this too far since long tuples are bad for your code's readability! Thank you very much for reading, and see you soon!