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 ...

  1. ... an instance of the set class if wrapped in curly braces (i.e., {a,b}).
  2. ... an instance of the list class if wrapped in square brackets (i.e., [a,b]).
  3. ... 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!

Ready to Learn More Web Development?

Join my Mailing List to receive one article per week.

I send one email per week on building performant and resilient Web Applications with Python, JavaScript and PostgreSQL. No spam. Unscubscribe at any time.

Continue Reading?

Here are a few more Articles for you ...

The Built-In all() Function

Learn how to use the built-in all() function in Python for boolean logic, with examples and different implementations.

By Christoph Schiessl on Python

Function Definition with Simple Parameters

Learn about functions with simple parameters in Python, including how the called can decide to use positional or keyword notation.

By Christoph Schiessl on Python

Function Definition with Default Parameters

Learn about Python functions with default parameters. Understand how default parameters work and some essential restrictions and evaluation rules.

By Christoph Schiessl on Python

Christoph Schiessl

Hi, I'm Christoph Schiessl.

I help you build robust and fast web applications.

I'm available for hire as a freelance web developer, so you can take advantage of the more than a decade of experience I have collected working on many projects across several industries. Most of my clients are building web-based SaaS applications in a B2B context and depend on my expertise in various capacities.

More often than not, my involvement includes hands-on development work using technologies like Python, JavaScript, and PostgreSQL. Furthermore, if you already have an established team, I can support you as a technical product manager with a passion for simplifying complex processes. Lastly, I'm also an avid writer and educator who takes pride in breaking down technical concepts into the simplest possible terms.