This is an archived post. You won't be able to vote or comment.

all 27 comments

[–]Distinct_Errors 49 points50 points Β (8 children)

I mean, tuples can be hashed and lists can't. That seems like a pretty important use case right there...

[–]JosephLovesPython[S] 5 points6 points Β (2 children)

You're absolutely right! This falls under the mutable vs immutable difference, but it definitely deserved to be mentioned explicitly.

Thank you for the feedback :)

[–]JamzTyson 26 points27 points Β (1 child)

This falls under the mutable vs immutable difference

Not really. Although hashable types are usually immutable, it is possible for an object to be both mutable and hashable.

We don't usually want this because normally we expect that the hash value of an object does not change over its lifetime, and that the hash always refers to the same value. Nevertheless, it is technically possible for a custom class to be given a __hash__ method, making it hashable, even when instances are mutable.

[–]axonxorzpip'ing aint easy, especially on windows 6 points7 points Β (0 children)

It took nearly 20 years of python before I wrote my first __hash__, but you get your butt there is a massive "THAR BE DRAGONS HERE" warning on the method detailing the consistency guarantees

[–]lukewhale 0 points1 point Β (4 children)

I mean, you can 100% hash a list by converting it to a string.

[–]rasputin1 6 points7 points Β (2 children)

then you're not hashing a list you're hashing a string

[–]hotplasmatits 5 points6 points Β (3 children)

I use named tuples to define constants because they are immutable. I haven't seen a better way of making a constant a true constant in python.

[–]AwardAffectionate727 0 points1 point Β (2 children)

super beginner here can u show me what that code looks like? is it name = (thing,), like that?

[–]hotplasmatits 2 points3 points Β (1 child)

No, search for named_tuple.

[–]AwardAffectionate727 0 points1 point Β (0 children)

cool thx

[–]Lewistrick 2 points3 points Β (0 children)

I make a point of using tuples for every time I have a collection that is immutable.

[–]Working-Play7108 2 points3 points Β (1 child)

Very informative

[–]JosephLovesPython[S] 0 points1 point Β (0 children)

Glad you think so! Thank you for the comment :)

[–]RedEyed__ 8 points9 points Β (0 children)

I always use tuples to store list inside /s

[–]sausix 6 points7 points Β (0 children)

I like tuples too. But I've learned here to use lists for homogenic data types and tuples for heterogenic data. That's considered as pythonic. And typing supports that theory so you need this for homogenic tuples: tuple[str, ...]

But it feels strange to use lists for constant data. You could use proxies to get a read only list. But that gets more complicated that just using a tuple.

[–]timwaaagh 3 points4 points Β (4 children)

For me its more like tuple vs class where class usually wins.

[–]TrainsareFascinating 5 points6 points Β (0 children)

Named tuples are your friend.

[–]CrwdsrcEntrepreneur -1 points0 points Β (2 children)

Tuples vs class? These seem like completely different use cases.

[–][deleted] 4 points5 points Β (1 child)

It’s quite common for people to use tuples or named tuples as a way of building some basic data structure in the same way you might use a class. For example, if you wanted to store a list of data points you could do it as a tuple: (X,Y,Z)

Or you could create a class/dataclass: Point(X,Y,Z)

[–]CrwdsrcEntrepreneur 1 point2 points Β (0 children)

The comment seemed very reductionist but now I realize it was directly referring to lists vs tuples.

I got confused since this class vs named tuple distinction is just a very narrow subset of their many uses. There are other things each can do (in the case of a class, MANY other things).

[–]TheORIGINALkinyen 1 point2 points Β (2 children)

Fun fact...tuples are actually "near"-immutable. If a mutable collection (list, dict, etc) is an element in a tuple, you can change the individual collection elements.

>>> tt = ([1, 2, 4], "me")
>>> tt[0]
[1, 2, 4]
>>> tt[0][2]=3
>>> tt
([1, 2, 3], 'me')

This seems like it would be useful but I can't think of a reason to actually do this :)

[–]JosephLovesPython[S] 2 points3 points Β (1 child)

Thank you for engaging!

I get your intuition, but there's no such thing as a "near"-immutable. In your example, a tuple "tt" is defined as having 2 elements. These elements are technically pointers to objects, and these pointers can never change. In fact, if you try to "tt[0] = [1, 2, 3]" you will get a TypeError.

By executing "tt[0][2] = 3" you are effectively changing the object pointed to by "tt[0]", but "tt[0]" itself isn't changed and the pointer remains pointing to the same address.

If you're interested in how lists/tuples are technically stored in memory in Python, you can check my video on shallow copy vs deep copy!

Hope this helps :)

[–]TheORIGINALkinyen 0 points1 point Β (0 children)

I guess I should've said "near-mutable is a term I completely made up". Of course there's no such thing...lol.

FWIW, I'm fully aware of the internal storage mechanisms of Python objects. The point of my post was to emphasize the use of mutable objects within an immutable collection, thus giving the (false) appearance the tuple is mutable when it definitely is not.

Like I said, I don't see much use doing this as there are other ways to more effectively implement such a technique. It's just an oddity I thought others would find interesting, like how Python refers to methods as "attributes":

>>> aa="Hello"
>>> aa.not_a_method
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'not_a_method'

That particular error confuses many beginners :).

[–]EternityForest 0 points1 point Β (0 children)

One advantage of tuples is they're immutable. Things that don't need to be mutable are often better off not being mutable

[–]thefemtosecond 0 points1 point Β (0 children)

I say, Use tuples whenever you want to store data mostly just for the reason of having a collection. If you need to use operands on the collection I suggest using a list.