7.3. Mapping Getitem

  • Key lookup is very efficient O(1)

  • [...] throws KeyError exception if key not found in dict

  • .get() returns None if key not found

  • .get() can have default value, if key not found

7.3.1. Getitem Method

  • If key exist - return value

  • If key is missing - raises KeyError exception

>>> data = {'firstname': 'Mark', 'lastname': 'Watney'}

If key exist:

>>> data['firstname']
'Mark'

If key is missing:

>>> data['age']
Traceback (most recent call last):
KeyError: 'age'

7.3.2. Get Method

  • If key exist - return value

  • If key is missing - None or default value (if specified)

>>> data = {'firstname': 'Mark', 'lastname': 'Watney'}

If key exist:

>>> data.get('firstname')
'Mark'

If key is missing:

>>> data.get('age')

If key is missing and default value is set:

>>> data.get('age', 'n/a')
'n/a'

7.3.3. Case Study - 1

>>> PL = {
...     'ą': 'a',
...     'ć': 'c',
...     'ę': 'e',
...     'ł': 'l',
...     'ń': 'n',
...     'ó': 'o',
...     'ś': 's',
...     'ż': 'z',
...     'ź': 'z',
... }

When key exists:

>>> letter = 'ą'
>>>
>>> PL[letter]
'a'
>>> PL.get(letter)
'a'

When key does not exist:

>>> letter = 'b'
>>>
>>> PL[letter]
Traceback (most recent call last):
KeyError: 'b'
>>>
>>> PL.get(letter)
>>>
>>> PL.get(letter, letter)
'b'

7.3.4. Case Study - 2

>>> def login(username, password):
...     ...

When all fields exist:

>>> data = {'username': 'mwatney', 'password': 'Ares3'}
>>>
>>> username = data['username']
>>> password = data['password']
>>>
>>> login(username, password)

If some fields are missing (password):

>>> data = {'username': 'mwatney'}

Getitem will raise an exception, which you can catch:

>>> try:
...     username = data['username']
...     password = data['password']
... except KeyError as error:
...     print(f'Cannot login without: {error}')
... else:
...     login(username, password)
...
Cannot login without: 'password'

Get method will need to add if-else to check if value is missing:

>>> username = data.get('username')
>>> password = data.get('password')
>>>
>>> if username is None:
...     print(f'Cannot login without: username')
... elif password is None:
...     print(f'Cannot login without: password')
... else:
...     login(username, password)
...
Cannot login without: password

7.3.5. Use Case - 1

>>> hello = {
...    'English': 'Hello',
...    'German': 'Guten Tag',
...    'Polish': 'Witaj',
... }
>>>
>>>
>>> hello.get('English')
'Hello'
>>>
>>> hello.get('Polish')
'Witaj'

7.3.6. Use Case - 2

>>> MONTHS = {
...     1: 'January',
...     2: 'February',
...     3: 'March',
... }
>>>
>>> MONTHS[1]
'January'
>>>
>>> MONTHS['1']
Traceback (most recent call last):
KeyError: '1'
>>>
>>> MONTHS['01']
Traceback (most recent call last):
KeyError: '01'

7.3.7. Use Case - 3

>>> MONTHS = {
...     1: 'January',
...     2: 'February',
...     3: 'March',
... }
>>>
>>> MONTHS.get(1)
'January'
>>>
>>> MONTHS.get(13)
>>>
>>> MONTHS.get(13, 'invalid month')
'invalid month'

7.3.8. Use Case - 4

>>> MONTHS = {
...     1: 'January',
...     2: 'February',
...     3: 'March',
...     4: 'April',
...     5: 'May',
...     6: 'June',
...     7: 'July',
...     8: 'August',
...     9: 'September',
...     10: 'October',
...     11: 'November',
...     12: 'December'
... }
>>>
>>> DATE = '1961-04-12'
>>>
>>> year, month, day = DATE.split('-')
>>>
>>> year
'1961'
>>> month
'04'
>>> day
'12'
>>>
>>> MONTHS[month]
Traceback (most recent call last):
KeyError: '04'
>>>
>>> MONTHS[int(month)]
'April'

7.3.9. Use Case - 4

>>> PAYROLL = [
...     {'name': 'Mark Watney',   'Jan': 2000, 'Feb': 2000, 'Mar': 2000},
...     {'name': 'Melissa Lewis', 'Jan': 3000, 'Feb': 3000, 'Mar': 3000},
...     {'name': 'Rick Martinez', 'Jan': 1000, 'Feb': 2000},
...     {'name': 'Alex Vogel',    'Jan': 2500, 'Feb': 2500, 'Mar': 2500},
... ]

Getitem:

>>> result = f'{"Employee":<15} {"January":>10} {"February":>9} {"March":>6}'
>>>
>>> for employee in PAYROLL:
...     name = employee['name']
...     january = employee['Jan']
...     february = employee['Feb']
...     march = employee['Mar']
...     result += f'{name:<15} {january:>10} {february:>9} {march:>6}'
...
Traceback (most recent call last):
KeyError: 'Mar'

Get method:

>>> result = f'{"Employee":<15} {"January":>10} {"February":>9} {"March":>6}\n'
>>>
>>> for employee in PAYROLL:
...     name = employee['name']
...     january = employee.get('Jan', '-')
...     february = employee.get('Feb', '-')
...     march = employee.get('Mar', '-')
...     result += f'{name:<15} {january:>10} {february:>9} {march:>6}\n'
>>>
>>> print(result)
Employee           January  February  March
Mark Watney           2000      2000   2000
Melissa Lewis         3000      3000   3000
Rick Martinez         1000      2000      -
Alex Vogel            2500      2500   2500

7.3.10. Assignments

# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% About
# - Name: Mapping Dict Getitem
# - Difficulty: easy
# - Lines: 1
# - Minutes: 2

# %% English
# 1. Use `DATA: dict`
# 2. Define `result: str` with value for key 'firstname' from `DATA`
# 3. Use getitem syntax
# 4. Run doctests - all must succeed

# %% Polish
# 1. Użyj `DATA: dict`
# 2. Zdefiniuj `result: str` z wartością dla klucza 'firstname' z `DATA`
# 3. Użyj składni getitem
# 4. Uruchom doctesty - wszystkie muszą się powieść

# %% Hints
# - `dict[key]`

# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

>>> from pprint import pprint

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

>>> pprint(result)
'Mark'
"""

DATA = {
    'firstname': 'Mark',
    'lastname': 'Watney',
    'group': 'users',
}

# Define `result: str` with value for key 'firstname' from `DATA`
# Use getitem syntax
# type: str
result = ...


# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% About
# - Name: Mapping Dict Get
# - Difficulty: easy
# - Lines: 1
# - Minutes: 2

# %% English
# 1. Use `DATA: dict`
# 2. Define `result: str` with value for key 'firstname'
# 3. Use `get` method
# 4. Run doctests - all must succeed

# %% Polish
# 1. Użyj `DATA: dict`
# 2. Zdefiniuj `result: str` z wartością dla klucza 'firstname'
# 3. Użyj metodę `get`
# 4. Uruchom doctesty - wszystkie muszą się powieść

# %% Hints
# - `dict.get(key)`

# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

>>> from pprint import pprint

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

>>> pprint(result)
'Mark'
"""

DATA = {
    'firstname': 'Mark',
    'lastname': 'Watney',
    'group': 'users',
}

# Define `result: str` with value for key 'firstname'
# Use `get` method
# type: str
result = ...


# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% About
# - Name: Mapping Dict GetDefault
# - Difficulty: easy
# - Lines: 1
# - Minutes: 2

# %% English
# 1. Use `DATA: dict`
# 2. Define `result: str` with value for key 'email'
# 3. If value does not exist in dict, return 'n/a'
# 4. Use `get` method with default value
# 5. Run doctests - all must succeed

# %% Polish
# 1. Użyj `DATA: dict`
# 2. Zdefiniuj `result: str` z wartością dla klucza 'email'
# 3. Jeżeli wartość nie istnieje w dict, zwróć 'n/a'
# 4. Użyj metody `get` z wartością domyślną
# 5. Uruchom doctesty - wszystkie muszą się powieść

# %% Hints
# - `dict.get(key, default)`

# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

>>> from pprint import pprint

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

>>> pprint(result)
'n/a'
"""

DATA = {
    'firstname': 'Mark',
    'lastname': 'Watney',
    'group': 'users',
}

# Define `result: str` with value for key 'email'
# If value does not exist in dict, return 'n/a'
# Use `get` method with default value
# type: str
result = ...


# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% About
# - Name: Mapping Dict Switch
# - Difficulty: medium
# - Lines: 2
# - Minutes: 3

# %% English
# 1. Use `DATA: dict` - with pilot's phonetic alphabet
# 2. Ask user to input letter
# 3. Define `result: str` with phonetic pronunciation of a letter
# 4. If the character does not exist in the alphabet, assign: 'Missing'
# 5. Non-functional requirements:
#    - User will always put only one capitalized letter
#    - User will not input any invalid characters or numbers
#    - Do not use `if`, `try`, and `except`
#    - `Mock` will simulate inputting `W` letter by a user
#    - Use `input()` function as normal
# 6. Run doctests - all must succeed

# %% Polish
# 1. Użyj `DATA: dict` - alfabet fonetyczny pilotów
# 2. Poproś użytkownika o wprowadzenie litery
# 3. Zdefiniuj `result: str` z fonetyczną wymową litery
# 4. Jeżeli znak nie istnieje w alfabecie, przypisz: 'Missing'
# 5. Wymagania niefunkcjonalne:
#    - Użytkownik zawsze wpisze tylko jedną wielką literę lub cyfrę
#    - Nie używaj `if`, `try`, i `except`
#    - `Mock` zasymuluje wpisanie litery `W` przez użytkownika
#    - Skorzytaj z funkcji `input()` tak jak normalnie
# 6. Uruchom doctesty - wszystkie muszą się powieść

# %% Hints
# - `input(prompt)`

# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

>>> from pprint import pprint
>>> import string

>>> assert letter is not Ellipsis, \
'Ask user to input letter and assign it to: `letter`'
>>> assert result is not Ellipsis, \
'Assign your result to variable `result`'
>>> assert type(result) is str, \
'Variable `result` has invalid type, should be str'

>>> pprint(result)
'Whisky'
"""

# Simulate user input (for test automation)
from unittest.mock import Mock
input = Mock(side_effect=['W', 'W'])


DATA = {
    'A': 'Alfa',
    'B': 'Bravo',
    'C': 'Charlie',
    'D': 'Delta',
    'E': 'Echo',
    'F': 'Foxtrot',
    'G': 'Golf',
    'H': 'Hotel',
    'I': 'India',
    'J': 'Juliet',
    'K': 'Kilo',
    'L': 'Lima',
    'M': 'Mike',
    'N': 'November',
    'O': 'Oscar',
    'P': 'Papa',
    'Q': 'Quebec',
    'R': 'Romeo',
    'S': 'Sierra',
    'T': 'Tango',
    'U': 'Uniform',
    'V': 'Victor',
    'W': 'Whisky',
    'X': 'X-Ray',
    'Z': 'Zulu',
}

# Ask user to input letter
# type: str
letter = input('Type letter: ')

# Define `result: str` with phonetic pronunciation of a letter
# If the character does not exist in the alphabet, assign: 'Missing'
# type: str
result = ...


# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% About
# - Name: Mapping Dict SwitchMatches
# - Difficulty: medium
# - Lines: 2
# - Minutes: 3

# %% English
# 1. Use `PL: dict` with Polish diacritic characters
# 2. Ask user to input single letter
# 3. Convert letter to lowercase
# 4. If letter is in `PL` then use conversion value for the letter
# 5. Non-functional requirements:
#    - User will always put only one capitalized letter
#    - User will not input any invalid characters or numbers
#    - Do not use `if`, `try`, and `except`
#    - Use `input()` function as normal
#    - `Mock` will simulate inputting `Ó` letter by a user
#    - Note that letter `Ó` is in `PL`
# 6. Run doctests - all must succeed

# %% Polish
# 1. Użyj `PL: dict` z polskimi znakami diakrytycznymi
# 2. Poproś użytkownika o wprowadzenie pojedynczej litery
# 3. Zamień literę na małą
# 4. Jeżeli litera jest w `PL` to użyj wartości konwersji dla litery
# 5. Wymagania niefunkcjonalne:
#    - Użytkownik zawsze wpisze tylko jedną wielką literę
#    - Użytkownik nie wpisze żadnych nieprawidłowych znaków lub cyfr
#    - Nie używaj `if`, `try`, i `except`
#    - Skorzytaj z funkcji `input()` tak jak normalnie
#    - `Mock` zasymuluje wpisanie litery `Ó` przez użytkownika
#    - Zwróć uwagę, że litera `Ó` jest w `PL`
# 6. Uruchom doctesty - wszystkie muszą się powieść

# %% Example
#     | Input | Output |
#     |-------|--------|
#     |   a   |    a   |
#     |   A   |    a   |
#     |   ą   |    a   |
#     |   Ą   |    a   |
#     |   b   |    b   |
#     |   B   |    B   |
#     |   c   |    c   |
#     |   C   |    c   |
#     |   ć   |    c   |
#     |   Ć   |    c   |
#     |  ...  |   ...  |

# %% Hints
# - `input()`
# - `str.lower()`

# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

>>> from pprint import pprint
>>> import string

>>> assert letter is not Ellipsis, \
'Ask user to input letter and assign it to: `letter`'
>>> assert result is not Ellipsis, \
'Assign your result to variable `result`'
>>> assert type(result) is str, \
'Variable `result` has invalid type, should be str'
>>> assert result not in PL.keys(), \
'Result should not be in PL dict'
>>> assert result in string.ascii_letters, \
'Result should be an ASCII letter'

>>> pprint(result)
'o'
"""

# %% Setup
# Simulate user input (for test automation)
from unittest.mock import Mock
input = Mock(side_effect=['Ó'])

PL = {
    'ą': 'a',
    'ć': 'c',
    'ę': 'e',
    'ł': 'l',
    'ń': 'n',
    'ó': 'o',
    'ś': 's',
    'ż': 'z',
    'ź': 'z',
}

# Ask user to input single letter
# Convert letter to lowercase
# type: str
letter = input('Type letter: ').lower()

# If letter is in `PL` then use conversion value for the letter
# Non-functional requirements:
# - Use `input()` function as normal
# - Note that letter `Ó` is in `PL`
# type: str
result = ...


# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`

# %% About
# - Name: Mapping Dict SwitchMissing
# - Difficulty: medium
# - Lines: 2
# - Minutes: 3

# %% English
# 1. Use `PL: dict` with Polish diacritic characters
# 2. Ask user to input single letter
# 3. Convert letter to lowercase
# 4. If letter is in `PL` then use conversion value for the letter
# 5. Non-functional requirements:
#    - User will always put only one capitalized letter
#    - User will not input any invalid characters or numbers
#    - Do not use `if`, `try`, and `except`
#    - Use `input()` function as normal
#    - `Mock` will simulate inputting `O` letter by a user
#    - Note that letter `O` is not in `PL`
# 6. Run doctests - all must succeed

# %% Polish
# 1. Użyj `PL: dict` z polskimi znakami diakrytycznymi
# 2. Poproś użytkownika o wprowadzenie pojedynczej litery
# 3. Zamień literę na małą
# 4. Jeżeli litera jest w `PL` to użyj wartości konwersji dla litery
# 5. Wymagania niefunkcjonalne:
#    - Użytkownik zawsze wpisze tylko jedną wielką literę
#    - Użytkownik nie wpisze żadnych nieprawidłowych znaków lub cyfr
#    - Nie używaj `if`, `try`, i `except`
#    - Skorzytaj z funkcji `input()` tak jak normalnie
#    - `Mock` zasymuluje wpisanie litery `O` przez użytkownika
#    - Zwróć uwagę, że litera `O` nie jest w `PL`
# 6. Uruchom doctesty - wszystkie muszą się powieść

# %% Example
#     | Input | Output |
#     |-------|--------|
#     |   a   |    a   |
#     |   A   |    a   |
#     |   ą   |    a   |
#     |   Ą   |    a   |
#     |   b   |    b   |
#     |   B   |    B   |
#     |   c   |    c   |
#     |   C   |    c   |
#     |   ć   |    c   |
#     |   Ć   |    c   |
#     |  ...  |   ...  |

# %% Hints
# - `input()`
# - `str.lower()`

# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

>>> from pprint import pprint
>>> import string

>>> assert letter is not Ellipsis, \
'Ask user to input letter and assign it to: `letter`'
>>> assert result is not Ellipsis, \
'Assign your result to variable `result`'
>>> assert type(result) is str, \
'Variable `result` has invalid type, should be str'
>>> assert result not in PL.keys(), \
'Result should not be in PL dict'
>>> assert result in string.ascii_letters, \
'Result should be an ASCII letter'

>>> pprint(result)
'o'
"""

# %% Setup
# Simulate user input (for test automation)
from unittest.mock import Mock
input = Mock(side_effect=['O'])


PL = {
    'ą': 'a',
    'ć': 'c',
    'ę': 'e',
    'ł': 'l',
    'ń': 'n',
    'ó': 'o',
    'ś': 's',
    'ż': 'z',
    'ź': 'z',
}

# Ask user to input single letter
# Convert letter to lowercase
# type: str
letter = input('Type letter: ').lower()

# If letter is in `PL` then use conversion value for the letter
# type: str
result = ...