7.5. Loop over dict

7.5.1. Looping over dict

  • Since Python 3.7 dict keeps order

  • Before Python 3.7 dict order is not ensured!!

7.5.1.1. Iterating

Listing 110. By default dict iterates over keys
iris = {
    'Sepal length': 5.1,
    'Sepal width': 3.5,
    'Petal length': 1.4,
    'Petal width': 0.2,
    'Species': 'setosa',
}

for obj in iris:
    print(obj)

# 'Sepal length'
# 'Sepal width'
# 'Petal length'
# 'Petal width'
# 'Species'

7.5.1.2. Iterating keys

Listing 111. Iterating over dict items
iris = {
    'Sepal length': 5.1,
    'Sepal width': 3.5,
    'Petal length': 1.4,
    'Petal width': 0.2,
    'Species': 'setosa',
}

list(iris.keys())
# ['Sepal length', 'Sepal width', 'Petal length', 'Petal width', 'Species']

for obj in iris.keys():
    print(obj)

# 'Sepal length'
# 'Sepal width'
# 'Petal length'
# 'Petal width'
# 'Species'

7.5.1.3. Iterating values

Listing 112. Iterating over dict items
iris = {
    'Sepal length': 5.1,
    'Sepal width': 3.5,
    'Petal length': 1.4,
    'Petal width': 0.2,
    'Species': 'setosa',
}

list(iris.values())
# [5.1, 3.5, 1.4, 0.2, 'setosa']

for obj in iris.values():
    print(obj)

# 5.1
# 3.5
# 1.4
# 0.2
# 'setosa'

7.5.1.4. Iterating key-value pairs

  • list of pairs key, value

Listing 113. Getting pair: key, value from dict items
iris = {
    'Sepal length': 5.1,
    'Sepal width': 3.5,
    'Petal length': 1.4,
    'Petal width': 0.2,
    'Species': 'setosa',
}

list(iris.items())
# [
#   ('Sepal length', 5.1),
#   ('Sepal width', 3.5),
#   ('Petal length', 1.4),
#   ('Petal width', 0.2),
#   ('Species', 'setosa'),
# ]


for key, value in iris.items():
    print(key, '->', value)

# Sepal length -> 5.1
# Sepal width -> 3.5
# Petal length -> 1.4
# Petal width -> 0.2
# Species -> setosa

7.5.2. Create dict from two sequences

7.5.2.1. range()

  • Pythonic way is to use zip()

  • Don't use len(range(...)) - it evaluates generator

Listing 114. Create dict from two list
header = ['Sepal length', 'Sepal width', 'Petal length', 'Petal width', 'Species']
data = [5.1, 3.5, 1.4, 0.2, 'setosa']
output = {}

for i in range(len(header)):
    key = header[i]
    value = data[i]
    output[key] = value

print(output)
# {
#   'Sepal length': 5.1,
#   'Sepal width': 3.5,
#   'Petal length': 1.4,
#   'Petal width': 0.2,
#   'Species': 'setosa',
# }

7.5.2.2. enumerate()

  • _ regular variable name (not a special syntax)

  • _ by convention is used when variable will not be referenced

Listing 115. Create dict from two list
header = ['Sepal length', 'Sepal width', 'Petal length', 'Petal width', 'Species']
data = [5.1, 3.5, 1.4, 0.2, 'setosa']
output = {}

for i, key in enumerate(header):
    output[key] = data[i]

print(output)
# {
#   'Sepal length': 5.1,
#   'Sepal width': 3.5,
#   'Petal length': 1.4,
#   'Petal width': 0.2,
#   'Species': 'setosa',
# }

7.5.2.3. zip()

  • The most Pythonic way

header = ['Sepal length', 'Sepal width', 'Petal length', 'Petal width', 'Species']
data = [5.1, 3.5, 1.4, 0.2, 'setosa']

output = dict(zip(header, data))

print(output)
# {
#   'Sepal length': 5.1,
#   'Sepal width': 3.5,
#   'Petal length': 1.4,
#   'Petal width': 0.2,
#   'Species': 'setosa',
# }

7.5.3. Assignments

7.5.3.1. dict to dict

English
  1. For input data (see below)

  2. Convert to Dict[str, str]

  3. Results should be identical to output (see below)

Polish
  1. Dla danych wejściowych (patrz sekcja input)

  2. Przekonwertuj do Dict[str, str]

  3. Rezultat powinien być identyczny do wyjściowego (patrz sekcja output)

Input
INPUT = {
    6: ['Doctorate', 'Prof-school'],
    5: ['Masters', 'Bachelor', 'Engineer'],
    4: ['HS-grad'],
    3: ['Junior High'],
    2: ['Primary School'],
    1: ['Kindergarten'],
}
Output
from typing import Dict


OUTPUT: Dict[str, str] = {
    'Doctorate': '6',
    'Prof-school': '6',
    'Masters': '5',
    'Bachelor': '5',
    'Engineer': '5',
    'HS-grad': '4',
    'Junior High': '3',
    'Primary School': '2',
    'Kindergarten': '1'
}
The whys and wherefores
  • Accessing dict items

  • Iterating over dict

  • Updating dict

7.5.3.2. List[tuple] to List[dict]

English
  1. For input data (see below)

  2. Separate header and data

  3. Print List[dict]

    • key - name from the header

    • value - measurement or species

Polish
  1. Dla danych wejściowych (patrz sekcja input)

  2. Odseparuj nagłówek i dane

  3. Wypisz List[dict]

    • klucz: nazwa z nagłówka

    • wartość: wyniki pomiarów lub gatunek

Input
INPUT = [
    ('Sepal length', 'Sepal width', 'Petal length', 'Petal width', 'Species'),
    (5.8, 2.7, 5.1, 1.9, 'virginica'),
    (5.1, 3.5, 1.4, 0.2, 'setosa'),
    (5.7, 2.8, 4.1, 1.3, 'versicolor'),
    (6.3, 2.9, 5.6, 1.8, 'virginica'),
    (6.4, 3.2, 4.5, 1.5, 'versicolor'),
    (4.7, 3.2, 1.3, 0.2, 'setosa'),
    (7.0, 3.2, 4.7, 1.4, 'versicolor'),
    (7.6, 3.0, 6.6, 2.1, 'virginica'),
    (4.9, 3.0, 1.4, 0.2, 'setosa'),
    (4.9, 2.5, 4.5, 1.7, 'virginica'),
    (7.1, 3.0, 5.9, 2.1, 'virginica'),
    (4.6, 3.4, 1.4, 0.3, 'setosa'),
    (5.4, 3.9, 1.7, 0.4, 'setosa'),
    (5.7, 2.8, 4.5, 1.3, 'versicolor'),
    (5.0, 3.6, 1.4, 0.3, 'setosa'),
    (5.5, 2.3, 4.0, 1.3, 'versicolor'),
    (6.5, 3.0, 5.8, 2.2, 'virginica'),
    (6.5, 2.8, 4.6, 1.5, 'versicolor'),
    (6.3, 3.3, 6.0, 2.5, 'virginica'),
    (6.9, 3.1, 4.9, 1.5, 'versicolor'),
    (4.6, 3.1, 1.5, 0.2, 'setosa'),
]
Output
from typing import List


OUTPUT: List[dict] = [
    {'Sepal length': 5.8, 'Sepal width': 2.7, 'Petal length': 5.1, 'Petal width': 1.9, 'Species': 'virginica'},
    {'Sepal length': 5.1, 'Sepal width': 3.5, 'Petal length': 1.4, 'Petal width': 0.2, 'Species': 'setosa'},
    {'Sepal length': 5.7, 'Sepal width': 2.8, 'Petal length': 4.1, 'Petal width': 1.3, 'Species': 'versicolor'},
    ...
]
The whys and wherefores
  • Working with nested data structures

  • Iterating over dict and lists

7.5.3.3. Label encoder

English
  1. For input data (see below)

  2. Define:

    • features: List[tuple] - measurements

    • labels: List[int] - species

  3. Separate header from data

  4. To encode and decode labels (species) we need label_encoder: Dict[int, str]:

    • key - id (incremented integer value)

    • value - species name

  5. label_encoder must be generated from INPUT

  6. For each row add appropriate data to features, labels and label_encoder

  7. Print features, labels and label_encoder

  8. Output must be identical to output data (see below)

Polish
  1. Dla danych wejściowych (patrz sekcja input)

  2. Zdefiniuj:

    • features: List[tuple] - pomiary

    • labels: List[int] - gatunki

    • label_encoder: Dict[int, str] - słownik podmiany nazw gatunków

  3. Odseparuj nagłówek od danych

  4. Aby móc zakodować i odkodować labels (gatunki) potrzebny jest label_encoder: Dict[int, str]:

    • key - identyfikator (kolejna liczba rzeczywista)

    • value - nazwa gatunku

  5. label_encoder musi być wygenerowany z INPUT

  6. Dla każdego wiersza dodawaj odpowiednie dane do feature, labels i label_encoder

  7. Wypisz feature, labels i label_encoder

  8. Wynik ma być identyczny z danymi wyjściowymi (patrz sekcja output)

Input
INPUT = [
    ('Sepal length', 'Sepal width', 'Petal length', 'Petal width', 'Species'),
    (5.8, 2.7, 5.1, 1.9, 'virginica'),
    (5.1, 3.5, 1.4, 0.2, 'setosa'),
    (5.7, 2.8, 4.1, 1.3, 'versicolor'),
    (6.3, 2.9, 5.6, 1.8, 'virginica'),
    (6.4, 3.2, 4.5, 1.5, 'versicolor'),
    (4.7, 3.2, 1.3, 0.2, 'setosa'),
    (7.0, 3.2, 4.7, 1.4, 'versicolor'),
    (7.6, 3.0, 6.6, 2.1, 'virginica'),
    (4.9, 3.0, 1.4, 0.2, 'setosa'),
    (4.9, 2.5, 4.5, 1.7, 'virginica'),
    (7.1, 3.0, 5.9, 2.1, 'virginica'),
    (4.6, 3.4, 1.4, 0.3, 'setosa'),
    (5.4, 3.9, 1.7, 0.4, 'setosa'),
    (5.7, 2.8, 4.5, 1.3, 'versicolor'),
    (5.0, 3.6, 1.4, 0.3, 'setosa'),
    (5.5, 2.3, 4.0, 1.3, 'versicolor'),
    (6.5, 3.0, 5.8, 2.2, 'virginica'),
    (6.5, 2.8, 4.6, 1.5, 'versicolor'),
    (6.3, 3.3, 6.0, 2.5, 'virginica'),
    (6.9, 3.1, 4.9, 1.5, 'versicolor'),
    (4.6, 3.1, 1.5, 0.2, 'setosa'),
]
Output
from typing import List, Dict


features: List[tuple] = [
    (5.8, 2.7, 5.1, 1.9),
    (5.1, 3.5, 1.4, 0.2),
    (5.7, 2.8, 4.1, 1.3),
    (6.3, 2.9, 5.6, 1.8),
    (6.4, 3.2, 4.5, 1.5),
    (4.7, 3.2, 1.3, 0.2), ...]

labels: List[int] = [0, 1, 2, 1, 2, 0, ...]

label_encoder: Dict[int, str] = {
    0: 'virginica',
    1: 'setosa',
    2: 'versicolor'}
The whys and wherefores
  • dict lookups

  • Dynamic dict generating

  • dict reversal