Mapping Types¶
Indices and tables¶
Definition¶
A mapping is a container type that stores a collection of zero or more key-value pairs. The keys must be hashable, but the values can be any arbitrary Python object.
Values need not all be the same type, and values can nest other container types.
Values in a mapping are indexed by key using the item access operator []
.
Dict¶
MUTABILITY: Mutable
The dict
(dictionary) is currently the only intrinsic mapping type defined by the Python data model.
Items in a dictionary are stored unordered.
Since dictionaries are mutable, you can modify the keys and values after creation without forcing Python to create a new object.
Dictionaries can be constructed in a variety of ways:
Using curly brackets
{}
. For example:To create a dictionary with 0 items:
>>> foo = {} >>> foo {}
To create a dictionary from key-value pairs using
:
as the separator:>>> foo = {'a': 1, 'b': 2, 'c': 3} >>> foo {'a': 1, 'b': 2, 'c': 3}
Using an expression in curly brackets
{}
to create a dict comprehension. For example:>>> foo = {'jim jones': ('Eng', 100), ... 'bim bartman': ('Eng', 341), ... 'jake king': ('Eng', 99), ... 'kyle zapp': ('Mkt', 921), ... 'moon yee': ('Mkt', 472), ... 'sun tzu': ('Mkt', 8294), ... 'tick tock': ('Fin', 46)} >>> bar = {key.title(): val[0] for key, val in foo.items()} >>> bar {'Bim Bartman': 'Eng', 'Jake King': 'Eng', 'Jim Jones': 'Eng', 'Kyle Zapp': 'Mkt', 'Moon Yee': 'Mkt', 'Sun Tzu': 'Mkt', 'Tick Tock': 'Fin'}
>>> baz = {key.title(): val[1] for key, val in foo.items() if val[0] == "Mkt"} >>> baz {'Kyle Zapp': 921, 'Moon Yee': 472, 'Sun Tzu': 8294}
Using the
dict
constructor, which allows you to do several things:With no arguments, it creates and empty dictionary:
>>> foo = dict() >>> foo {}
With arguments passed as keywords, it uses the first as the key and the second as the value:
>>> foo = dict(a=1, b=2, c=3) >>> foo {'a': 1, 'b': 2, 'c': 3}
Note
You can only use keyword arguments to the
dict
constructor if the keys are considered valid Python identifiers. For example, the key, “jim bob” is not a valid Python identifier and it’s use would result in aSyntaxError
being thrown.When passed a sequence, where each item in the sequence is itself a sequence of 2 objects, it builds the dictionary using the first object as the key and the second as the value:
>>> foo = dict([('a', 1), ('b', 2), ('c', 3)) >>> foo {'a': 1, 'b': 2, 'c': 3}
When passed a dictionary, this is one way of shallow-copy ing the dictionary:
>>> foo = {'a': 1, 'b': 2, 'c': 3} >>> bar = dict(foo) >>> bar {'a': 1, 'b': 2, 'c': 3}
Individual items in a mapping can be indexed using the item access operator []
, which takes a key, as in, [key]
.
If key doesn’t exist, you will get a KeyError
.
Tip
To avoid getting a KeyError
for keys that don’t exist, you can use the collections.defaultdict
type, which has all the same methods as the dict
class, but, allows you to specify a default value to use for keys that don’t exist. If an attempt is made to access the dictionary using a key that doesn’t exist, the key is created and the value set to the default value. For example:
>>> import collections
>>> foo = collections.defaultdict(int)
>>> foo['a']
>>> foo['b']
>>> foo
defaultdict(int, {'a': 0, 'b': 0})
Due to the fact that mappings store unordered items, it is not possible to slice or stride them.
Dictionaries compare equal if the have the same key:value pairs. For example:
>>> foo = {'a': 1, 'b': 2, 'c': 3}
>>> bar = {'b': 2, 'c': 3, 'a': 1}
>>> baz = {'d': 4, 'e': 5, 'f': 6}
>>> bif = {'a': 1, 'b': 2}
>>> foo == bar
True
>>> foo == baz
False
>>> foo == bif
False
Dictionaries don’t support comparing using <
, <=
, >
and >=
.
Dict Specific Methods¶
The dict type supports the operations shown in Table 11.
Operation | Description |
---|---|
len(d) | Return the number of items in the dictionary >>> foo = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
>>> len(foo)
5
|
d[key] | Return the item of Raises >>> foo = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
>>> foo['a']
1
|
d[key] = val | Sets >>> foo = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
>>> foo['a'] = 99
>>> foo
{'a': 99, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
|
del d[key] | Remove the item of Raises >>> foo = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
>>> del foo['a']
>>> foo
{'b': 2, 'c': 3, 'd': 4, 'e': 5}
|
key in d | Membership testing. Returns >>> foo = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
>>> 'a' in foo
True
|
key not in d | Membership testing. Returns >>> foo = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
>>> 'z' not in foo
True
|
iter(d) | Returns an iterator over the keys of the dictionary. Allows dict objects to be iterated over using >>> foo = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
>>> for key in foo:
... print("{}:{}".format(key, foo[key]))
b:2
c:3
d:4
e:5
a:1
|
d.items() | Return a new view of the dictionary’s items (its (key, value) pairs). >>> foo = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
>>> foo.items()
dict_items([('b', 2), ('c', 3), ('d', 4), ('e', 5), ('a', 1)])
>>> list(foo.items())
[('b', 2), ('c', 3), ('d', 4), ('e', 5), ('a', 1)]
>>> for item in foo.items():
... print(item)
('b', 2)
('c', 3)
('d', 4)
('e', 5)
('a', 1)
|
d.keys() | Returns a view of the dictionary’s keys. >>> foo = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
>>> foo.keys()
dict_keys(['b', 'c', 'd', 'e', 'a'])
>>> list(foo.keys())
['b', 'c', 'd', 'e', 'a']
>>> for key in foo.keys():
... print(key)
b
c
d
e
a
|
d.values() | Return a new view of the dictionary’s values. >>> foo = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
>>> foo.values()
dict_values([2, 3, 4, 5, 1])
>>> list(foo.values())
[2, 3, 4, 5, 1]
>>> for val in foo.values():
... print(val)
2
3
4
5
1
|
d.clear() | Removes all items from the dictionary >>> foo = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
>>> foo.clear()
>>> foo
{}
|
d1 = d0.copy() | Return a shallow copy of dictionary >>> foo = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
>>> bar = foo.copy()
>>> bar
{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
|
dict.fromkeys(seq[, val]) | Create new dictionary with keys from >>> foo = dict.fromkeys(['a', 'b', 'c'], 1)
>>> foo
{'a': 1, 'b': 1, 'c': 1}
|
d.get(key[, default]) | Return the value for Never raises >>> foo = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
>>> foo.get('f', 99)
99
|
d.pop(key[, default]) | If If not, return >>> foo = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
>>> foo.pop('c')
3
>>> foo
{'a': 1, 'b': 2, 'd': 4, 'e': 5}
|
d.popitem() | Remove and return an arbitrary (key, value) pair from the dictionary. >>> foo = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
>>> foo.popitem()
('b', 2)
>>> foo
{'a': 1, 'c': 3, 'd': 4, 'e': 5}
|
d.setdefault(key[, default]) | If If not, insert key with a value of
>>> foo = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
>>> foo.setdefault('f', 99)
99
>>> foo
{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 99}
|
d.update([x]) | Update the dictionary Existing keys are overwritten.
>>> foo = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
>>> foo.update({'f': 6})
>>> foo.update([('g', 7), ('h', 8)])
>>> foo.update(i=9)
>>> foo
{'a': 1,
'b': 2,
'c': 3,
'd': 4,
'e': 5,
'f': 6,
'g': 7,
'h': 8,
'i': 9}
|
The methods, items()
, keys()
and values()
return dictionary view objects. These are read-only objects that can be iterated over and who’s content changes when the underlying dictionary changes.
The advantage to dictionary view objects is they allow set
type operations on them if their contents are unique.
Note
Dictionary keys are always unique. Dictionary values may or may not be unique. Dictionary items are unique only if keys and values are all unique.
For example:
Union (return a new set with elements from the set and all others)
>>> foo = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5} >>> bar = {'a': 99, 'f': 6, 'g': 7} >>> bif = {'a': 200, 'c': 444, 'h': 555} >>> foo.keys() | bar.keys() | bif.keys() {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}Intersection (return a new set with elements common to the set and all others)
>>> foo = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5} >>> bar = {'a': 99, 'f': 6, 'g': 7} >>> bif = {'a': 200, 'c': 444, 'h': 555} >>> foo.keys() & bar.keys() & bif.keys() {'a'}Difference (return a new set with elements in the set that are not in the others)
>>> foo = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5} >>> bar = {'a': 99, 'f': 6, 'g': 7} >>> bif = {'a': 200, 'c': 444, 'h': 555} >>> foo.keys() - bar.keys() - bif.keys() {'b', 'd', 'e'}
Try it!
Try the following:
Create an empty dict.
Add the following key:value pairs to the empty dict you just created:
- ‘girls’ : 3
- ‘boys’ : 5
- ‘dogs’ : 1
Copy the following dictionary:
{'John' : ('Hamilton', 20), 'Sam' : ('Hamilton', 32), 'Cass' : ('Toronto', 52), 'Nathan': ('Toronto', 36), 'Alison': ('Hamilton', 27), 'Erin' : ('Toronto', 43), 'Kevin' : ('Burlington', 62), 'Julia' : ('Toronto', 58) }
Get the keys from the copy of the dictionary above.
Remove “Nathan” from the copy of the dictionary above.
Merge the first dictionary above with the copy of the dictionary above.