How to Create a Tuple Comprehension in Python

If you’ve ever used a list comprehension in Python, you might have wondered if there is a way to create a tuple comprehension.

The short answer is: there is no direct way to create a tuple comprehension in Python.

Why Is There No Tuple Comprehension in Python?

You can’t create a tuple comprehension in Python because you can’t append items to a tuple once it’s created. So looping over an iterable and appending items to a tuple is not possible.

However, there are ways to create a tuple using a list comprehension or a generator expression.

Solution #1: Create a Tuple Using a List Comprehension

You can create a tuple using a list comprehension by wrapping the list comprehension in the `tuple()` function.

>>> tuple([x for x in range(5)])

(0, 1, 2, 3, 4)

Solution #2: Create a Tuple Using a Generator Expression

You can also create a tuple using a generator expression by wrapping the generator expression in the `tuple()` function.

>>> tuple(x for x in range(5))

(0, 1, 2, 3, 4)

Notice the subtle difference between the two solutions:

  • The first solution uses square brackets to create a list comprehension, then wraps the list comprehension in the `tuple()` function.
  • The second solution uses parentheses to create a generator expression, and calls the `tuple()` function on the generator expression.

If you don’t use the `tuple()` function in the second solution, the generator expression will create a generator object instead of a tuple.

>>> (x for x in range(5))

<generator object <genexpr> at 0x7f9b8c0b9f10>

Which Solution Should You Use?

While the second solution is more readable, let’s check the performance of both solutions.

import time

def timeit(func):
    def wrapper(*args, **kwargs):
        results = []
        for i in range(10):
            start = time.process_time()
            result = func(*args, **kwargs)
            end = time.process_time()
            results.append(end - start)
        print(f"{func.__name__} took on average {sum(results) / len(results)} seconds")
    return wrapper

iterations = 10**7 # We'll create a tuple with 10 million items

@timeit
def create_tuple_with_list_comprehension():
    return tuple([x for x in range(iterations)])

@timeit
def create_tuple_with_generator_expression():
    return tuple(x for x in range(iterations))

create_tuple_with_list_comprehension()
create_tuple_with_generator_expression()

Using Google Colab, I ran the above code and got the following results:

create_tuple_with_list_comprehension took on average 0.9761280782999997 seconds
create_tuple_with_generator_expression took on average 0.9290617158999996 seconds

As you can see, the first solution is slightly slower than the second solution, with a decrease in performance of 4.82%.

Obviously, this is a very simple example.

The performance difference might be very different in your code (depending on the number of iterations and the complexity of your comprehension).

So make sure to test both solutions in your code to see which one is faster.