Dictionaries
Dictionary is mutable mapping type (also know as hash or key-value collection).
In other words it's structure of key-value elements. Keys can be only hashable objects (all immutable objects and instances of classes). Values can be of any type.
Keys/values elements are unordered (their position in memory is based on result of hash()
function used on a key.
Ways to create a dictionary:
{}
dict()
{"name": "John", "surname": "Snow"}
dict(name="John", surname="Snow")
Result of dict(some_dict)
will be shallow copy of some_dict
We can create a copy with some new keys:
🪄 Code:
📟 Output:
We can even rewrite some old key-values:
🪄 Code:
📟 Output:
And also we can create a dict from an iterable with pair key-value
🪄 Code:
📟 Output:
Using method dict.fromkeys
we can create a new dict from an iterable (some collection) of keys. Second attribute will allow to set a default value for all keys (or it will be None
).
🪄 Code:
📟 Output:
🪄 Code:
📟 Output:
It is recommended to pass some immutable object as the default value. Otherwise you could get unexpected results:
🪄 Code:
📟 Output:
🪄 Code:
📟 Output:
There are (from 3.5) even more craziest ways of dict creation:
🪄 Code:
📟 Output:
🪄 Code:
📟 Output:
How dictionaries work
🔥
Dictionary lookup is done in three steps:
A hash value of the key is computed using a hash function.
hash functions provided must guarantee that if two keys produce different hash values then the two key objects are not equivalent
that's why
objectA == objectB
it's also needed thathash(objectA) == hash(objectB)
The hash value addresses a location in d.data which is supposed to be an array of "buckets" or "collision lists" which contain the (key,value) pairs.
The collision list addressed by the hash value is searched sequentially until a pair is found with
pair[0] == key
. The return value of the lookup is thenpair[1]
.
🔥
🔥
That's why for dictionaries keys we can use only those objects that support hash function (e.g. through __hash__
), equality comparison (e.g. through __eq__
or __cmp__
), and must satisfy the correctness condition above.
And that's why mutable objects (like lists) can't have __hash__()
- even if we base on id()
we just can't guarantee that two lists won't be equal in future.
On the contrary, by default, all user defined types (instances of class
) are usable as dictionary keys with hash(object)
defaulting to id(object)
.
Main methods of dictionaries
🪄 Code:
📟 Output:
Dictionary methods
Method(s) | Description |
---|---|
| Return a number of keys in dictionary |
| Return (or assign) value for key |
| Return value for key |
| Return True/False - is key |
| Return a view object that provides an access to all keys in dictionary |
| Return a view object that provides an access to all values in dictionary |
| Return a view object that provides an access to all |
| Remove element by key from dictionary |
Method(s) | Description |
---|---|
| Return value and remove key from dictionary ( |
| Return tuple |
| Update dictionary with key-values of |
| Update dictionary with key-values pairs: "x1": "y1", "x2": "y2", ... |
| Empty whole dictionary (the same as |
| Return shallow copy of dictionary |
| Set value |
Examples
🪄 Code:
📟 Output:
🪄 Code:
📟 Output:
🪄 Code:
📟 Output:
Method get
get
Trying to obtain unexistent key will be resulted in KeyError
exception
🪄 Code:
📟 Output:
More correctly:
🪄 Code:
📟 Output:
Even better - use get()
Using
get
is very "pythonic"
Shorter!
Only 1 (instead of 2) requests to dict
Can specify a default value
🪄 Code:
📟 Output:
Method setdefault
setdefault
This method allows to write a "default" value for specific key and/or return set or that default value. In other words it will update dictionary only when the key is not found in it.
🪄 Code:
📟 Output:
So, the code:
🪄 Code:
📟 Output:
is the same as:
🪄 Code:
📟 Output:
If the default value is a list it can used for appending the needed value right away:
🪄 Code:
📟 Output:
Method update
update
Doc says:
The same syntax can be used with dict()
.
🪄 Code:
📟 Output:
🪄 Code:
📟 Output:
And crazy example - two syntaxes altogether:
🪄 Code:
📟 Output:
Deleting
Regular del
here too:
🪄 Code:
📟 Output:
To clear all keys it is possible to use clear()
🪄 Code:
📟 Output:
Also - just like with lists we have pop()
and popitem()
methods.
pop(k [,v])
will return value by keyk
or default valued
popitem()
will return last added pair (from Python 3.6) OR some random pair (before Python 3.6)(key, value)
and raiseKeyError
if dict is empty
🪄 Code:
📟 Output:
Dictionary view objects
The methods dict.keys()
, dict.values()
and dict.items()
return so-called view
objects in Python 3 (in Python 2 they return a list of corresponding values - all keys, all values and all key-value pairs).
View objects provide a dynamic view on the dictionary's data, which means that when the dictionary changes, the view reflects these changes right away.
Changes per versions:
3.7
: Dictionary order is guaranteed to be insertion order.3.8
: Dictionary views are now reversible.
Dictionary views can be iterated over to yield their respective data, support membership tests and basic set
-like operations like &
and |
(which is union
and intersection
):
len(dictview)
Return the number of entries in the dictionary.
iter(dictview)
Return an iterator over the keys, values or items (represented as tuples of (key, value)) in the dictionary.
x in dictview
Return True if x is in the underlying dictionary’s keys, values or items (in the latter case, x should be a (key, value) tuple).
reversed(dictview)
Return a reverse iterator over the keys, values or items of the dictionary. The view will be iterated in reverse order of the insertion.
Some examples of usage dictviews
objects:
🪄 Code:
📟 Output:
Check how dynamic are dictviews
:
🪄 Code:
📟 Output:
Dictionary comprehesions
🪄 Code:
📟 Output:
Not so oftenly used because:
🪄 Code:
📟 Output:
Sometimes dictionary comprehension is useful when you need to set a default mutable value (so dict.fromkeys
is not good)
🪄 Code:
📟 Output:
## Complexity of operations
🔥
Operation | Average Case | Amortized Worst Case |
---|---|---|
Copy | O(n) | O(n) |
Get Item | O(1) | O(n) |
Set Item[1] | O(1) | O(n) |
Delete Item | O(1) | O(n) |
Iteration | O(n) | O(n) |
Last updated