Skip to main content

Return Values, Unpacking, and Multi-Result Design

The phrase "Python can return multiple values" is very common, but a more accurate way to put it is: Python packs multiple return values into a tuple, which you then unpack on the calling side.

The Most Basic Return

def square(x):
return x * x

Returning Multiple Values

def min_max(values):
return min(values), max(values)


low, high = min_max([3, 1, 5, 2])

This is essentially equivalent to:

def min_max(values):
return (min(values), max(values))

Unpacking

point = (3, 5)
x, y = point

Star unpacking is also very common:

first, *middle, last = [1, 2, 3, 4, 5]

When to return a tuple

Suitable for these situations:

  • Small number of return values
  • The order of return values is clear
  • The values naturally belong together

Examples: coordinates, min and max, width and height.

When to return a dictionary or data class

If the number of return values grows, the order becomes hard to remember, or the meaning isn't obvious enough, don't force a tuple.

def get_user():
return {
"name": "alice",
"score": 95,
"city": "Chengdu",
}

Going further, you can use dataclass:

from dataclasses import dataclass


@dataclass
class User:
name: str
score: int
city: str

return and yield are not the same

If a function gives results all at once, use return.

If a function wants to produce results one at a time, use a generator with yield:

def countdown(n):
while n > 0:
yield n
n -= 1

My own decision criteria

  • Two or three results with clear meaning: tuple
  • Many fields with meaning that needs to be explicit: dictionary or data class
  • Want to produce results incrementally: generator