Why in Python can we define an index of a Dict as a Tuple?

4

I noticed that in Python, we can add values of type tuple as index of a dict (dictionary).

Example:

test = {}

test[(1, 2, 3)] = ("um", "dois", "tres")

print test // {(1, 2, 3): ('um', 'dois', 'tres')}

And after the definition, how do we access the value for the key we defined as tuple ?

And what is the purpose of this?

    
asked by anonymous 17.06.2015 / 17:17

3 answers

2

Python dictionaries do not have to have restrictions on how data structures are implemented in other languages.

The constraints for an object to be used as a key for a dictionary are: the object must implement a __hash__ method that returns a single constant value; the object has equality comparison with other objects ( __eq__ ) - and that neither hash nor equality condition varies while the object is a dictionary key. In general, for simplicity we say that immutable objects can be dictionary keys - but following such constraints even mutable objects can serve.

What "usefulness" varies enormously: it depends on what you want to do - tuples are usually practical because they let you use a dictionary as a sparse array, of course - just use the "get" method to get values:

W = H = 10
a = {}
a[5,5] = 1
print ("\n".join(", ".join(str(a.get((x,y), 0))  for x in range(W))  for y in range(H)) )

In this example, I use the index in the get method because it allows you to specify a default value for when the key does not exist - (which happens for all combinations of x and y, minus the (5.5) that I declare ). The output is:

0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 1, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0

Tuples are exceptionally practical because the surrounding parentheses can be omitted when used in an unambiguous context - such as indices within brackets (see example above).

But objects that represent date and time, with rich comparisons, frozen sets, even functions can be used as dictionary keys (in log applications, for example, that count the number of times a function is called, or that they cache) - it's cool not to have an artificial restriction.

A context in which different keys should be taken care of is in applications that have to serialize the data as JSON, such as rest APIs, or calls to some non-relational databases: the JSON standard requires that the chavves are strings.

    
17.06.2015 / 18:37
3

To access, we only use tuple as a key, following your example:

print test[(1,2,3)] #Isso retornará ('um', 'dois', 'tres')

Regarding the usefulness of this, it will depend on its implementation. For example, imagine a database that a certain set of values in a row return me a value, I could use tuple for that purpose to access a specific value.

    
17.06.2015 / 17:36
1

Complementing the other responses, numpy (a library for doing matrix operations) abuses this fact to allow you to do block operations:

  • If M is a numpy.array , M[5:10, 10:15] is a 5 × 5 array consisting of the elements at the intersection of the 5th to the 9th lines of M with the 10th to 14th column of M ; li>
  • If L is a one-dimensional vector, L[numpy.array([1, 1, 2, 3, 5, 8, 13, 21])] is a vector consisting only of the elements in the positions of the Fibonacci sequence;
  • If N is any array, N[N < 0] = -N assigns% to N to the absolute value of each of its entries.

numpy documentation has more creative abuses of Python indexing.

(Yes, it is true that numpy.array is not a dictionary, but an object that overloads its __getitem__ method to allow M[…] , but I think this is a good example of why it is useful to allow arbitrary objects between the brackets.)

    
17.06.2015 / 22:11