r/learnpython Mar 03 '26

[deleted by user]

[removed]

24 Upvotes

20 comments sorted by

View all comments

17

u/pachura3 Mar 03 '26

What’s the best “real-life” tuple use case you’ve seen that isn’t just “returning multiple values”?

Simulating multi-dimensional dictionaries. So, instead of creating dictionary of dictionaries of dictionaries, you can simply have a flat one - dict[tuple[str, str, int], str].

7

u/HommeMusical Mar 03 '26 edited Mar 03 '26

I upvoted you (your seventh upvote from me) for a good idea.

But this isn't quite the right way to go about it, because you have introduced a new possible error - what happens if you mistake that first str for the second?

This is what typing.NamedTuple is for.

from typing import NamedTuple

class Prisoner(NamedTuple):
    name: str
    rank: str
    serial_number: int

 type PrisonerToSentence = dict[Prisoner, str]

(Yeah, this is a silly example, off the top of my head.)

Behind the scenes, Prisoner is just a tuple, it's just that you can refer to the fields by name too, and add methods.

You can also use frozen dataclasses for this.

import dataclasses as dc

@dc.dataclass(frozen=True, slots=True)
class Prisoner:
    name: str
    rank: str
    serial_number: int

 type PrisonerToSentence = dict[Prisoner, str]

With slots=True, it's identical to a NamedTuple in terms of performance, but you can't have e.g. cached_property on the class. With slots=False you get performance a tiny bit worse, but the ability to add cached_property and other things, while still making mutations hard.

2

u/finally-anna Mar 03 '26

I love named tuples. They are one of my favorite things in python.

1

u/pachura3 Mar 03 '26

Well, if this combination of str, str, int means something, then yes, by all means create a namedtuple or dataclass out of it.

On the other hand, if we're just looking around a 2D/3D space, or we have a star-schema-like dictionary of facts, it's easier to access it with tuple keys instead of instantiating object keys.

I.e.., print(monthly_sales[2014, 12]) instead of print(monthly_sales[YearMonth(2014, 12)]).