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!

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 my more than a decade of experience 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 an avid writer and educator who takes pride in breaking technical concepts down into the simplest possible terms.

Continue Reading?

Here are a few more Articles for you ...


How to <link> your Blog's Atom/RSS Feed from HTML Pages

Learn how to <link> Atom and RSS feeds from your HTML documents to make them discoverable for clients and, by extension, for your readers.

By Christoph Schiessl

Exploring Orphaned Branches to Understand Git's Internals

Learn about Git's internal data structure and how orphaned branches can be used to create separate histories with their own root commits.

By Christoph Schiessl on DevOps and Git

How to Serve a Directory of Static Files with FastAPI

Learn how to serve a static site using FastAPI. Perfect for locally testing statically generated websites, for instance, with httpie.

By Christoph Schiessl on Python and FastAPI

Web App Reverse Checklist

Ready to Build Your Next Web App?

Get my Web App Reverse Checklist first ...


Software Engineering is often driven by fashion, but swimming with the current is rarely the best choice. In addition to knowing what to do, it's equally important to know what not to do. And this is precisely what my free Web App Reverse Checklist will help you with.

Subscribe below to get your free copy of my Reverse Checklist delivered to your inbox. Afterward, you can expect one weekly email on building resilient Web Applications using Python, JavaScript, and PostgreSQL.

By the way, it goes without saying that I'm not sharing your email address with anyone, and you're free to unsubscribe at any time. No spam. No commitments. No questions asked.