5.3. Mapping Keys

5.3.1. Valid Keys

  • hashable

>>> data = {
...     1: 'red',
...     2: 'green',
...     3: 'blue',
... }
>>> data = {
...     1.1: 'red',
...     2.2: 'green',
...     3.3: 'blue',
... }
>>> data = {
...     'a': 'red',
...     'b': 'green',
...     'c': 'blue',
... }
>>> data = {
...     True: 'red',
...     False: 'green',
...     None: 'blue',
... }
>>> data = {
...     (1,2,3): 'red',
...     (4,5,6): 'green',
...     (7,8,9): 'blue',
... }

5.3.2. Invalid Keys

  • unhashable

  • list, set and dict cannot be a key

>>> data = {
...     [1,2,3]: 'red',
...     [4,5,6]: 'green',
...     [7,8,9]: 'blue',
... }
Traceback (most recent call last):
TypeError: unhashable type: 'list'
>>> data = {
...     {1,2,3}: 'red',
...     {4,5,6}: 'green',
...     {7,8,9}: 'blue',
... }
Traceback (most recent call last):
TypeError: unhashable type: 'set'
>>> data = {
...     {1: None, 2:None, 3:None}: 'red',
...     {4: None, 5:None, 6:None}: 'green',
...     {7: None, 8:None, 9:None}: 'blue',
... }
Traceback (most recent call last):
TypeError: unhashable type: 'dict'

5.3.3. Get Keys

In Python 2, the methods items(), keys() and values() used to "take a snapshot" of the dictionary contents and return it as a list. It meant that if the dictionary changed while you were iterating over the list, the contents in the list would not change. In Python 3, these methods return a view object whose contents change dynamically as the dictionary changes. Therefore, in order for the behavior of iterations over the result of these methods to remain consistent with previous versions, an additional call to list() has to be performed in Python 3 to "take a snapshot" of the view object contents. 1

>>> crew = {
...    'commander': 'Melissa Lewis',
...    'botanist': 'Mark Watney',
...    'pilot': 'Rick Martinez',
... }
>>>
>>>
>>> crew.keys()
dict_keys(['commander', 'botanist', 'pilot'])
>>>
>>> list(crew.keys())
['commander', 'botanist', 'pilot']

5.3.4. Use Case - 0x01

>>> calendarium = {
...    1961: 'First Human Space Flight',
...    1969: 'First Step on the Moon',
... }

5.3.5. Use Case - 0x02

>>> calendarium = {
...    1961: ['First Russian Space Flight', 'First US Space Flight'],
...    1969: ['First Step on the Moon'],
... }

5.3.6. References

1

Frédéric Hamidi. Why does Python 3 need dict.items to be wrapped with list()? Retrieved: 2021-02-28. URL: https://stackoverflow.com/a/17695716

5.3.7. Assignments

Code 5.2. Solution
"""
* Assignment: Mapping Define Dict
* Required: yes
* Complexity: easy
* Lines of code: 3 lines
* Time: 3 min

English:
    1. Create `result: dict` representing input data
    2. Non-functional requirements:
        a. Assignmnet verifies creation of `dict()`
        b. Do not parse `DATA`, simply model `result` based on `DATA`
        c. Do not use `str.split()`, `slice`, `getitem`, `for`, `while` or
           any other control-flow statement
    3. Run doctests - all must succeed

Polish:
    1. Stwórz `result: dict` reprezentujący dane wejściowe
    2. Wymagania niefunkcjonalne:
        a. Zadanie sprawdza tworzenie `dict()`
        b. Nie parsuj `DATA`, po prostu zamodeluj `result` bazując na `DATA`
        c. Nie używaj `str.split()`, `slice`, `getitem`, `for`, `while` lub
           jakiejkolwiek innej instrukcji sterującej
    3. Uruchom doctesty - wszystkie muszą się powieść

Tests:
    >>> import sys; sys.tracebacklimit = 0

    >>> assert type(result) is dict, \
    'Variable `result` has invalid type, should be dict'

    >>> assert 'First Name' in result.keys(), \
    'Value `First Name` is not in the result keys'

    >>> assert 'Last Name' in result.keys(), \
    'Value `Last Name` is not in the result keys'

    >>> assert 'Missions' in result.keys(), \
    'Value `Missions` is not in the result keys'

    >>> assert 'Jan' in result['First Name'], \
    'Value `Jan` is not in the result values'

    >>> assert 'Twardowski' in result['Last Name'], \
    'Value `Twardowski` is not in the result values'

    >>> assert 'Apollo' in result['Missions'], \
    'Value `Apollo` is not in the result values'

    >>> assert 'Artemis' in result['Missions'], \
    'Value `Artemis` is not in the result values'
"""

DATA = """
    First Name: Jan
    Last Name: Twardowski
    Missions: Apollo, Artemis
"""

# dict[str,str|list]: with First Name, Last Name and Missions as keys
result = ...