this post was submitted on 29 Sep 2021
7 points (88.9% liked)

Python

3235 readers
1 users here now

News and discussions about the programming language Python


founded 5 years ago
MODERATORS
 

The only differences are that tuples are immutable and that lists have extra methods.

Is there ever a strong need for list-type data to be immutable? Evough to justify a whole extra data-type in the language?

Should they release a python 4 with it removed?

The only thing I can think of is as a default function parameter. This function is okay:

def dothings(a=(1,2)):
    print(a)
    a = (a[0], 3)

But this function misbehaves the second time it is called:

def dothings(a=[1,2]):
    print(a)
    a[1] = 3

But IMO the "mutable arguments" thing is another bug to be fixed in a hypothetical python 4. And even in python 3 you just write the function the recommended way, so there is not such a big problem.

def dothings(a=None):
    if a is None:
        a = [1, 2]
    print(a)
    a[1] = 3

The Python devs are clever guys though. There must be some really important reason to maintain both types?

top 16 comments
sorted by: hot top controversial new old
[–] tmpod 10 points 3 years ago* (last edited 3 years ago) (2 children)

The only differences are that tuples are immutable and that lists have extra methods.

No exactly. Lists should be homogeneous while tuples can be heterogeneous. Lists are unhashable, but tuples are hashable.
These are important distinctions.

Sure, technically speaking you could remove data types like tuples and still achieve the same thing pretty easily (look at Lua with just tables), however, having these different structures can go a long way to making code more readable, which is, after all, one of the big Python goals.

Edit: typo

[–] SeerLite@lemmy.ml 2 points 3 years ago (1 children)

Lists should be homogeneous while tuples can be heterogeneous.

Could you explain this bit, please? I've always understood that both can have both kinds of elements.

Do you mean that in the usual contexts they're used? Like: lists usually hold a variable number of things of the same type while tuples are sometimes expected to hold values of different kinds in a specific order. Something like that?

[–] tmpod 3 points 3 years ago* (last edited 3 years ago)

While lists can be heterogeneous (hold elements of differing types), their main purpose is not it, but rather to be a homogeneous ordered collections of elements. There are very little cases where you actually need a dynamic ordered collection with an heterogeneous set of elements.
Tuples, on the other hand, provide a structure of heterogeneous data. They should, in fact, not be seen as "immutable" lists, even though they can act as such. So much so, as you have namedtuple which acts very akin to a C struct.

Python is a very expresive language with a mostly clean syntax and nice data types as first-class citizens. This allows for code that clearly describes what you want. Sure, you could essentially use lists for every collection, and for structures, but that wouldn't be clear at all.

Edit: fixed fat fingered abomination lol

[–] roastpotatothief@lemmy.ml 0 points 3 years ago (1 children)

Lists are hererogeneous. This is valid:

mylist = [1, 1.0, "one"]

For homogeneous lists, shouldn't you be using numpy anyway?

Hashing. This is a interesting point, and it's not mentioned when people usually compare lists and tuples. I read this. It seems like dicts are both mutable and hashable, and that's not a problem. Python could implement a __hash__() method for lists too.

I'm starting to think that it's purely a whimsical thing. Lists are probably implemented as linked lists in memory, but tuples are probably sequential in memory. So it might be interesting for the devs to have both for these fundamental memory structures available.

[–] tmpod 1 points 3 years ago* (last edited 2 years ago) (1 children)

While lists can be heterogeneous, you shouldn't do it. And no, I don't want to pull a massive dependency when I don't need to.

Regarding dicts, they are also not hashable, I'm unsure where you got that info from. In fact, the SO post you linked states exactly that:

A hash should remain unchanged throughout the lifetime of the object.

This means any dynamic structures shouldn't really have hashes. Both lists and dicts are dynamic, so they are not hashable. A nice and easy way to see this is by trying he following in a Python shell:

>>> {{}: 1}
TypeError: unhashable type: 'dict'
>>> # or
>>> {[]: 1}
TypeError: unhashable type: 'list'

And yeah, what you said about the underlying implementation is also true. It is handy and interesting to have both types of structures.

Edit: hit save instead of preview for some reason lol

Edit 2: Also forgot to mention that the tuple / list thing is found in functional languages a lot, and also in Rust and whatnot. Remember, lists provide order, while tuples provide structure.

[–] roastpotatothief@lemmy.ml 1 points 3 years ago (1 children)

from here. this says that dicts are hashable, no?

A hash is useful in identification of objects. For example, it speeds up data retrieval from a dict, identifying the arbitrary value of a key by a single numerical value from a finite interval - the key's hash.

oh wait the keys are hashable but the dict is not. understood. the keys are (immutable) strings.

all this stylistic stuff, i just really see it as important. maybe because I'm new to programming, i think it's most important for things to be simple. to remove redundancy and extra complexity. the niche stuff like namedtuple and hashable lists (ie tuples) can be hidden in some package.

like in numpy there might be 5 methods that all do the same thing. they are there because stylistically, you might prefer one over the other, for neatness or readability etc. i would like to have only one way (or method or data type) to do one thing.

[–] tmpod 1 points 3 years ago (2 children)

oh wait the keys are hashable but the dict is not.

Exactly :)

the keys are (immutable) strings.

this is partially correct. Keys can be strings (which are immutable, and thus hashable), but they can be anything that implements the magic/dunder method __hash__.

all this stylistic stuff, i just really see it as important. maybe because I’m new to programming, i think it’s most important for things to be simple. to remove redundancy and extra complexity. the niche stuff like namedtuple and hashable lists (ie tuples) can be hidden in some package.

named tuples are in a package, while tuples are not. As I said previously, tuples are not immutable/hashable lists, even though you can treat them as such, similar to how you can use integers instead of booleans (in fact, True and False are just aliases to 1 and 0, respectively), despite that being a bad idea. Sure, it adds one extra syntax, but Python aims at being readable, and while you argue this goes against that principle, I argue exactly the opposite. Having different syntax for order (lists), structure (tuples), membership + other math operations (sets) and relation (dicts) is one of the core reasons why Python scripts can and are easy to read. The intentions behind each variable are really clear precisely because you have these fundamental types.

Now, you're right in that it may be a bit overwhelming when you're just starting to know the language, but I'd argue that, if you read good resources, it shouldn't be very hard to grasp the differences between those types, why they exist and what their use-cases are.

Also, don't forget that knowledge is highly cumulative; you have to slowly build your skills, topic by topic, and each step depends on the last one. I hope to have contributed to your better understanding of these Python data structures (which are actually implementations of their broader abstract definitions) :3

[–] tmpod 1 points 3 years ago

Also, to add on to that, if you wish an even simpler language, with really just one collection and structure type, look at Lua

[–] roastpotatothief@lemmy.ml 0 points 3 years ago* (last edited 3 years ago) (1 children)

I do see what you mean. I'm not sure why it's important to have different datatypes for structure/order and not for other things. You could have different syntaxes for volumes, distances, and coefficients. You don't need a separate data-type for each type of quantity, but you could. It would make certain types of algorithms more readable.

print(id(True))

9476448

print(id(1))

9788608

In what sense is True an alias for 1? It's a boolean not an integer. It really is a different data-type. It would be more reasonable to remove integers and just use floats. Those two are much more similar.

It's an interesting way of thinking, and has this whole "pythonic" philosophy, experimenting with different ways of thinking. Thanks for sharing. As I said these are not the usual explanations I've found on the internet. Your explanations are a bit more convincing than those.

[–] tmpod 1 points 3 years ago* (last edited 3 years ago)

I do see what you mean. I’m not sure why it’s important to have different datatypes for structure/order and not for other things. You could have different syntaxes for volumes, distances, and coefficients. You don’t need a separate data-type for each type of quantity, but you could. It would make certain types of algorithms more readable.

Those would be units, not actual data collections/structures, like lists, tuples and so on. They are different things. It wouldn't make sense to have a type for each unit, and it would also be unfeasible to do so. Having different core types for order, structrue, relation and math sets is important, however.

print(id(True))

9476448

print(id(1))

9788608

In what sense is True an alias for 1? It’s a boolean not an integer. It really is a different data-type.

You're right, I misremembered it. But, booleans are in fact subclasses of integers.

It would be more reasonable to remove integers and just use floats. Those two are much more similar.

No, it would not be reasonable. Not only are floats a bad replacement for ints, but I'd argue it would go against Python's principle of being simple but highly flexible and easy to understand. As I've stated, having these different primitive types helps a lot when trying to convey intention.

It’s an interesting way of thinking, and has this whole “pythonic” philosophy, experimenting with different ways of thinking.

Yeah. I also have to say that the term "pythonic" is thrown around a lot and it has a very foggy definition. The Zen of Python (import this) is equally as often cited and, while it certainly provides some nice guidelines, it mustn't be taken word by word. In many ways, the Python language doesn't comply with its Zen, in some situations for good, and others for not so good.

Thanks for sharing. As I said these are not the usual explanations I’ve found on the internet. Your explanations are a bit more convincing than those.

You're welcome! I've found this exchange rather fruitful as it hopefully shed some light on the matter and made me have to take a step back and think clearly about my reasoning. It's great to have these kinds of discussions and have your views challenged :3

[–] birokop@lemmy.ml 3 points 3 years ago (1 children)

Don't really know python but i think your lists are quite performance heavy because of all the features, while tuples are closer to arrays in a language like java, and are simple memory blocks that can be worked with much faster. Don't take my word for it though :P

[–] roastpotatothief@lemmy.ml 0 points 3 years ago* (last edited 3 years ago) (1 children)

This could be the right answer. I know tuples use slightly less memory. But I'm not if that's so important. I don't think programs ever need to iterate over 1 million tuple entries, where speed or memory would be important.

[–] ksynwa@lemmy.ml 0 points 3 years ago

One important reason why tuples exist is that unlike lists they are immutable. So they are hashable and can be used as keys in dictionaries among other things.

[–] ksynwa@lemmy.ml 2 points 3 years ago (1 children)

Should they release a python 4 with it removed?

No lol

[–] roastpotatothief@lemmy.ml 0 points 3 years ago (1 children)

TBH I'm building up to a longer post, where I describe the (IMO) single major flaw in python, and how to fix it, and that this fix is not backward-compatible and justifies a new version number.

[–] ksynwa@lemmy.ml 0 points 3 years ago

Ah OK. Sorry for being an ass. I thought you were new to programming and dunning-kruger'd into a hasty opinion. Sorry for presuming.