Skip to content

Multiple Return Values Tuple Unpacking Python Guide

Updated: at 02:01 AM

In Python, functions can return multiple values by returning them inside of a tuple. This allows a function to have more than one output, which can be useful in many situations. The process of receiving multiple return values from a function is called “tuple unpacking.”

This article will provide a comprehensive guide on using multiple return values and tuple unpacking in Python. We will cover the following topics:

Table of Contents

Open Table of Contents

What are Tuples?

In Python, a tuple is an immutable ordered sequence of elements. Tuples are created by placing comma-separated values inside parentheses (). For example:

my_tuple = (1, 2, 3)

Tuples can contain mixed data types like integers, floats, strings etc.

mixed_tuple = (1, "Hello", 3.4)

Tuples are immutable, meaning the elements inside a tuple can’t be changed once the tuple is created. However, tuples itself can be reassigned to new elements.

my_tuple = (1, 2, 3)
my_tuple = ("a", "b", "c") # reassigning to new tuple

These immutable properties make tuples useful for cases where you want to ensure the values don’t change.

Now that we know what tuples are, let’s look at how to return multiple values from a function using tuples.

Returning Multiple Values from a Function

In Python, we can return multiple values from a function using a tuple. Here is an example:

def min_max(numbers):
    min = numbers[0]
    max = numbers[0]

    for n in numbers:
        if n < min:
            min = n
        if n > max:
            max = n

    return min, max # Returning tuple

nums = [1, 2, 34, -4, 5]
min_max_nums = min_max(nums)
print(min_max_nums)

# Output: (-4, 34)

In the above min_max() function, we calculate both the minimum and maximum value of a given list of numbers. Instead of returning just the min or max, we return both values as a tuple.

When calling the function, it returns a tuple that contains the min as the first element and max as the second element.

This allows the function to output multiple values in a single return statement.

Tuple Unpacking to Receive Multiple Return Values

When a function returns multiple values in a tuple, we can unpack them into separate variables using tuple unpacking.

Tuple unpacking allows you to assign each element of a tuple to its own variable.

For example:

def calculate(x, y):
   sum = x + y
   product = x * y
   return sum, product

sum, product = calculate(5, 6)

print(sum) # 11
print(product) # 30

Here calculate() returns a two-element tuple containing the sum and product of the inputs.

When calling calculate(), we use tuple unpacking by assigning the first returned element to sum, and the second element to product.

This lets us access the individual return values separately in the variables sum and product.

Use Cases and Examples of Multiple Return Values

Some common use cases for returning multiple values from a function include:

Returning min and max of a collection:

def min_max(numbers):
    # Implementation
    return min_num, max_num

Parsing strings:

def parse_string(input_str):
    # Split string
    return first_word, second_word

Statistical calculations:

def stats(data):
    # Statistical computations
    return mean, standard_deviation

Web scraping results:

def scrape_website(url):
    # Scrape data
    return titles, links, descriptions

User credentials:

def authenticate_user(username, password):
    # Check credentials
    return access_token, refresh_token

As you can see, returning multiple values allows the function output to be more informative and useful in many scenarios.

Advantages of Multiple Return Values

Some key advantages of using multiple return values via tuple unpacking include:

Disadvantages of Multiple Return Values

Some disadvantages to be aware of:

So while multiple return values have many uses, they should be used judiciously where appropriate and not overused.

Tuple Unpacking Assignment

Python allows unpacking tuples into variables in an assignment statement.

For example:

min_max_nums = (-4, 34) # Tuple from some calculation

min_num, max_num = min_max_nums

print(min_num) # -4
print(max_num) # 34

Here we assign the tuple min_max_nums directly to variables min_num and max_num using tuple unpacking.

The number of variables on the left must match the length of the tuple.

This provides a convenient way to access tuple elements without indexing the tuple.

Unpacking Tuples into Variables

We can unpack any tuple into separate variables, not just return values from functions.

For example:

user = ("John", "Doe", 30)

first_name, last_name, age = user

print(first_name) # John
print(age) # 30

Here we unpack the user tuple into three variables directly.

This lets you access tuple elements by meaningful names instead of indices.

Unpacking Tuples During Function Calls

You can even unpack tuples during function calls:

def full_name(first, last):
    return first + " " + last

user = ("John", "Doe")

print(full_name(*user)) # John Doe

The * operator unpacks the user tuple into positional arguments when calling full_name().

This allows passing tuples or lists directly to functions without extracting elements manually.

Extended Tuple Unpacking

Tuple unpacking also supports extended unpacking with the following features:

Using _ to Ignore Values

If you want to ignore certain tuple values, use _ as the variable name:

_, last_name, _ = user
print(last_name) # Doe

Here we ignore the first and last element, only assigning the middle one.

Unpacking to Remaining Variables with *

You can unpack remaining tuple values to a list using *:

first_name, *other = user

print(first_name) # John
print(other) # ['Doe', 30]

This assigns the first tuple element to first_name, and remaining to other.

Catch All Unpacking with *

Similarly, * can be used at the start to catch all values in a list:

*values, last = user

print(values) # ['John', 'Doe']
print(last) # 30

Here all except the last element are unpacked into values.

Combining Regular and Extended Unpacking

You can also combine regular, extended, and catch all unpacking in powerful ways:

first_name, *middle_names, last_name = ("John", "Randolph", "Doe")

This lets you flexibly unpack tuples of any size.

Named Tuple Unpacking

Python’s collections module provides named tuples that have fields accessible by name.

For example:

from collections import namedtuple

User = namedtuple('User', ['name', 'age'])

user = User('John', 30)

Named tuples can also be unpacked like regular tuples:

name, age = user
print(name) # John

But they allow accessing fields by name:

print(user.name) # John

So named tuples combine readability of names with unpacking.

Unpacking Tuples in for Loops

Tuple unpacking is commonly used when iterating over list of tuples:

users = [("John", 30), ("Mike", 20), ("Sarah", 35)]

for name, age in users:
    print(f"{name} is {age} years old")

This loops through each tuple in users and unpacks the elements into name and age variables.

Tuple unpacking in for loops provides a cleaner way to access the tuple elements directly.

Tuple Unpacking with Variable Length Arguments

Functions that accept variable length positional arguments can also use tuple unpacking.

For example, sum() can take any number of arguments:

nums = (1, 2, 3)
sum(*nums) # 6

Here *nums unpacks the tuple into separate arguments 1, 2, 3 when calling sum().

This works for any function that takes *args.

Tuple Unpacking Best Practices

To effectively leverage tuple unpacking, keep these best practices in mind:

By following these best practices, you can write clean and robust code using multiple return values and tuple unpacking in Python.

Conclusion

This guide covered the key aspects of multiple return values and tuple unpacking in Python. We discussed:

Multiple return values via tuple unpacking provide a simple way for functions to output multiple values. When used properly, they can produce concise and readable code.

Tuple unpacking eliminates the need to access returned tuples by index. Overall, multiple return values are a useful feature in Python that are worth understanding and applying when suitable.