Python: variable-length tuples

[Python 3.1]

I follow the design concept that tuples should be of known length (see this comment ), and unknown tuples of length should be replaced by lists in most circumstances. My question is under what circumstances should I deviate from this rule?

For example, I understand that tuples are faster to create from string and number literals than lists (see another comment ). So, if I have performance-critical code that has numerous calculations, such as sumproduct(tuple1, tuple2) , should I redefine them to work on lists, despite the performance hit? ( sumproduct((x, y, z), (a, b, c)) is defined as x * a + y * b + z * c , and its arguments are indefinite, but equal in length).

What about the tuple that Python automatically creates when using def f(*x) ? I suggest that this is not something that I should be forced to list every time I use it.

Btw, (x, y, z) faster to create than [x, y, z] (for variables, not literals)?

+4
performance python list tuples
source share
5 answers

In my opinion, the only interesting difference between tuples and lists is that lists are mutable, but tuples are not. Other differences that people mention seem completely artificial to me: tuples are like structures, and lists are like arrays (that's where “tuples should be of known length” come from). But how is structuredness aligned with immutability? This is not true.

The only difference that matters is the difference that language makes: variability. If you need to modify an object, be sure to use the list. If you need a hash object (like a key in a dict or a collection item), then you need it to be immutable, so use a tuple. What is it.

+10
source share

I always use the most appropriate data structure to work with, and don't worry about whether a tuple can save me half a millisecond here or there. Prefusing code does not usually pay off at the end. If the code runs too slowly, you can always profile it and change 0.01% of the code, where it really matters.

All that you are talking about is related to the implementation of the python version and the equipment used. You can always use these things for yourself to see what they will be on your machine.

A common example of this is that "old immutable strings are slowly concatenating" in python. This was true about 10 years ago, and then they changed the implementation to 2.4 or 2.5. If you do your own tests, they now work faster than lists, but people are still convinced of this and use stupid constructs that actually work slower!

+3
source share

Under what circumstances should I deviate from the rule [should the courts be of known length]?

Missing.

This is a matter of significance. If an object has a value based on a fixed number of elements, then this is a tuple. (x, y), (c, m, y, k) colors, (lat, lon), etc. etc.

A tuple has a fixed number of elements based on the domain in general, and features of the problem.

Designing a tuple with an indefinite number of elements makes little sense. When do we go from (x, y) to (x, y, z) and then to the coordinates (x, y, z, w)? Not by simply matching the value, as if it is a list? If we go from 2-d to 3-d coordinates, there is usually pretty nice math to map coordinate systems. Do not add an item to the list.

What does the transition from (r, g, b) colors to something else mean? What is the 4th color in rgb system? For that matter, what is the fifth color in the cmyk plane?

Tuples do not change .

*args is a tuple because it is immutable. Yes, it has an indefinite number of arguments, but it is a rare counter expression for tuples of known, defined sizes.


What to do with an indefinite tuple of length. This counter example is so deep that we have two options.

  • Rejection of the very idea that tuples are of fixed length and are limited by the problem. The very idea of ​​coordinates (x, y) and (r, g, b) colors is completely useless and wrong due to this counter example. Fixed-length tuples? Never.

  • Always convert all *args to lists to always have a fussy level of thoughtless compliance with the design principle. Hidden list? Always.

I like everything or nothing, because they make the software so simplistic and thoughtless.

Perhaps in these corner cases a tiny shred of “this requires thinking” is here. Tiny scrap.

Yes, *args is a tuple. Yes, this is an indefinite length. Yes, this is a counter example where “fixed by a problem domain” is “just unchanged”.

This leads us to the third choice in the case when the sequence is unchanged for another reason. You will never mutate it, so it is normal if it were a short indefinite size. In the even rarer case, when you expose *args , because you consider it as a stack or a queue, then you may need to make a list from it. But we cannot solve all the possible problems.

Thinking is sometimes required.


When you design, you create a tuple for some reason. Overlay a meaningful structure on your data. The number of elements with a fixed length? Tuple. A variable number of elements (i.e., variable)? List.

+2
source share

Tuple is much simpler than a list. Use them wherever you can live with them, being unthinkable.

0
source share

In this case, you should probably consider using numpy and numpy arrays.

There are some utility conversions to and from numpy arrays, but if you do a bunch of calculations, it will be much faster

0
source share

All Articles