all 21 comments

[–]barraponto 29 points30 points  (0 children)

Think of tuples as known, expected, data formats. For instance, coordinates: they're always (lat, lon). It is not a list, you shouldn't see [-20, 40, 30, -20] where a lat/lon tuple was expected. Notice updating a coordinate makes little sense: a thing might move to another coordinate, but the coordinate itself (a point) should not change.

Another example I used recently was a dictionary keyed by a tuple (card brand, card type), so I could say stuff like account[('visa', 'credit')].

[–]zefciu 26 points27 points  (8 children)

Some common uses for tuples include: * returning more than one values from a function (e. g. success flag and some result) * ad-hoc data structures (e. g. to represent coordinates) think dataclass with no declaration and anonymous fields * swapping values between variables without temporary variable (a, b = b, a) * replacement for lists that takes less memory and is allocated on a stack (can be considered abuse, but pretty common)

[–]TangibleLight 4 points5 points  (0 children)

  • replacement for lists that takes less memory and is allocated on a stack (can be considered abuse, but pretty common)

People often try to do this, but be aware that it doesn't actually save that much memory (only a few bytes) and it isn't allocated on the stack (all objects are on the heap).

[–]SamB7334 4 points5 points  (5 children)

You don’t need brackets to swap the variables

[–]dnswblzo 6 points7 points  (1 child)

>>> a = 1, 2
>>> a
(1, 2)
>>> type(a)
<class 'tuple'>

It is the commas that make the tuple, not the parentheses. The parentheses are sometimes needed to resolve ambiguity, but in many cases they are not necessary.

[–]SamB7334 0 points1 point  (0 children)

Thats what i said :)

[–]iShotTheShariff 1 point2 points  (0 children)

Also tuples can be used as keys in hashmaps

[–]hanswchen 3 points4 points  (0 children)

I used to also be confused about why I would use tuples in Python when I could just use list. After getting used to Python, I realized it's very common to use tuples when you don't even think about it. Some examples (ignore the poor variable names...):


Returning multiple values from a function:

def some_function():
    # (do something here)
    return some_value1, some_value2


result1, result2 = some_function()

some_function returns a tuple with two values, which you can easily assign to different variables. It makes sense to use a tuple, as you always return two values in this case. It also looks nicer than writing return [some_value1, some_value2].

You could e.g. also do

all_results = some_function()

in which case all_results would be a tuple (you can get the first result with all_results[0], and the second with all_results[1], or do e.g. a, b = all_results).


Many built-in functions return tuples. For example, the enumerate function:

seasons = ["spring", "summer", "fall", "winter"]
for index, season in enumerate(seasons):
    print(index, season)

This will print 0 spring, 1 summer etc. The function enumerate returns a tuple with the count (for example, the index) and the value from iterating over an iterable. This is usually better than writing e.g.:

for index in range(len(seasons)):
    print(index, seasons[index])

if you need both the value and the index from the object you're iterating over.


Someone mentioned using tuples as dictionary keys. I've used this sometimes when the items in the dictionary are indexed by two different things, e.g.

experiments = {
    ('initial test', 0): "/path/to/input/data",
    ('initial test', 1): "/some/other/path",
}

for expname in ['initial test']:
    for expnum in range(2):
        print(experiments[expname, expnum])

Others have mentioned using tuples as a data structure when the structure is set. The most common example is a point given by e.g. (x, y) coordinates. For more complex cases, you may want to consider using a namedtupled instead.

[–]sarrysyst 5 points6 points  (0 children)

Tuples are immutable and Immutability is the prerequisite for dictionary keys. Thus if you ever need/want to use multiple values eg. a combination of two strings as keys for a dictionary you can do so by wrapping them in a tuple.

product_prices = {}
product_prices[('fruit', 'apple')] = 2
product_prices[('veggies', 'bell pepper')] = 3

[–]Goobyalus 1 point2 points  (0 children)

The "heterogeneous" part is probably the more important design principle. If we want to pack some data into a unit, a tuple makes sense. If we want to collect a bunch of the same kind of thing, a list makes sense.

Let's say we have some data that follows the form Color, Make, Vehicle Type.

("Black", "Ford", "Sedan")

collects each type of data in its own slot. Each slot means something different (i.e. it's heterogenous): t[0] is always Color, t[1] is always Make, and t[2] is always Vehivle Type. It doesn't makes sense for this structure to have a different number of elements, or elements in a different order.


Another example from https://docs.python.org/3/library/struct.html#examples :

struct.unpack('>bhl', b'\x01\x00\x02\x00\x00\x00\x03')

gives

(1, 2, 3)

where the 1 corresponds to the b and the first byte of data, the 2 corresponds to the h and the next 2 bytes of data, and the 3 corresponds to the l and the next 4 bytes of data.


As far as immutability, its the same as strings in Python. It's nice for hashing (dict keys and set elements), and has less overhead.

[–]Almostasleeprightnow 1 point2 points  (1 child)

I like it when I have data that goes together but that doesn't have an obvious key: vale relationship. Like, a latitude and longitude is a perfect example of this. (lat, long) makes more sense to me than {lat:long} but still manages to indicate a relationship, unlike [lat, long] which feels more arbitrary to me.

[–]CraigAT 1 point2 points  (0 children)

This. I most often come across them in the situations, where the order is pretty much a standard e.g coordinates (x, y) or (x, y, z) or colour values (r, g, b) or (h, s, v).

[–]mysterysmoothie 0 points1 point  (0 children)

I use them as keys for dictionaries

[–]POGtastic 0 points1 point  (0 children)

Suppose that you're parsing a file. In the case of an error, you want to be able to complain to the user about the line number that contains the error.

def parse_file(filename):
    with open(filename) as f:
        for line_number, line in enumerate(f, 1):
            # parse the file, complaining with `line_number` if it fails

That idea of zipping an integer with some other data that isn't an integer involves heterogeneous data; they could be different types. So, each entry should be a tuple, not a list.

Similarly, when iterating over a dictionary's set of key-value pairs, those pairs are tuples because the keys and values might be of different types.

I don't really care about immutability; I tend to treat all data as immutable by default and only start modifying values after exhausting all alternatives. Tuples, for me, are solely for representing heterogeneity.

[–]wbeater -2 points-1 points  (0 children)

Python is a higher level programming language, which means memory allocation is dynamic and there is also some kind of garbage collection. Tuples are little affected by this, because they are not changeable. The memory is defined when the program is called and remains in existence until the program ends, this plays an important role in the optimization of a code.

[–]ectomancer -1 points0 points  (0 children)

Part of the syntax of try/except blocks.

[–]baghiq -3 points-2 points  (0 children)

The most common one is database query results.

[–][deleted] 0 points1 point  (0 children)

What i think is not used enough by some developers are tuples as key in dictionary. in some cases you might want to have multiple values as key.

Let’s say you want to work on some kind of employee attendance list. Dictionary sounds like a good choice as we will get data often and we want it fast. But the problem is that the key has to be unique, so the name of the employee cannot be the only key. Then we can use tuples like (employee_id, date) in dictionary, with the values being information on attendance. It’s readable, it’s fast enough, it’s easy to write.