Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: how does a dict with mixed key type work?

Tags:

python

I understand that the following is valid in Python: foo = {'a': 0, 1: 2, some_obj: 'c'}

However, I wonder how the internal works. Does it treat everything (object, string, number, etc.) as object? Does it type check to determine how to compute the hash code given a key?

like image 723
Fabian Avatar asked May 31 '15 04:05

Fabian


People also ask

Can a dictionary have mixed data types for the keys in Python?

Python dictionary is a container of key-value pairs. It is mutable and can contain mixed types. A dictionary is an unordered collection. Python dictionaries are called associative arrays or hash tables in other languages.

Can Python dictionary have keys of different types?

The values of a dictionary can be of any type, but the keys must be of an immutable data type such as strings, numbers, or tuples.

Can Python dictionary have different data types?

Almost any type of value can be used as a dictionary key in Python. You can even use built-in objects like types and functions.

What happens when two keys are given while declaring a dictionary?

No, each key in a dictionary should be unique. You can't have two keys with the same value. Attempting to use the same key again will just overwrite the previous value stored. If a key needs to store multiple values, then the value associated with the key should be a list or another dictionary.


2 Answers

Types aren't used the same way in Python as statically types languages. A hashable object is simply one with a valid hash method. The interpreter simply calls that method, no type checking or anything. From there on out, standard hash map principles apply: for an object to fulfill the contract, it must implement both hash and equals methods.

like image 71
jwilner Avatar answered Oct 16 '22 01:10

jwilner


You can answer this by opening a Python interactive prompt and trying several of these keys:

>>> hash('a')
12416037344
>>> hash(2)
2
>>> hash(object())
8736272801544

Does it treat everything (object, string, number, etc.) as object?

You are simply using the hash function to represent each dictionary key as an integer. This integer is simply used to index in the underlying dictionary array. Assuming a dictionary starts of with a pre-allocated size of 8, we use the modulus operator (the remainder) to fit it into an appropriate location:

>>> hash('a')
12416037344
>>> hash(object()) % 8
2

So in this particular case, the hashed object is placed in index 2 of the underlying array. Of course there can be collisions, and so depending on the underlying implementation, the underlying array may actually be an array of arrays.

Note that items that aren't hashable cannot be used as dictionary keys:

>>> hash({})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'

Proof:

>>> d = {}
>>> d[{}] = 5
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'
like image 25
14 revs, 12 users 16% Avatar answered Oct 16 '22 02:10

14 revs, 12 users 16%