6.5. Loop over Dict

6.5.1. Rationale

  • Since Python 3.7 dict keeps order

  • Before Python 3.7 dict order is not ensured!!

6.5.2. Iterate

Listing 6.34. 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'

6.5.3. Iterate Keys

Listing 6.35. 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'

6.5.4. Iterate Values

Listing 6.36. 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'

6.5.5. Iterate Key-Value Pairs

  • list of pairs key, value

Listing 6.37. 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

6.5.6. Generate with Range

  • range()

  • Pythonic way is to use zip()

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

Listing 6.38. 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']
result = {}

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

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

6.5.7. Generate with Enumerate

  • enumerate()

  • _ regular variable name (not a special syntax)

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

Listing 6.39. 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']
result = {}

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

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

6.5.8. Generate with Zip

  • 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']

result = dict(zip(header, data))

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

6.5.9. Assignments

6.5.9.1. dict to dict

English
  1. Use data from "Input" section (see below)

  2. Convert to result: Dict[str, str]

  3. Compare result with "Output" section (see below)

Polish
  1. Użyj danych z sekcji "Input" (patrz poniżej)

  2. Przekonwertuj do result: Dict[str, str]

  3. Porównaj wyniki z sekcją "Output" (patrz poniżej)

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


result: 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

6.5.9.2. List[tuple] to List[dict]

English
  1. Use data from "Input" section (see below)

  2. Separate header and data

  3. Print List[dict]:

    • key - name from the header

    • value - measurement or species

  4. Compare result with "Output" section (see below)

Polish
  1. Użyj danych z sekcji "Input" (patrz poniżej)

  2. Odseparuj nagłówek i dane

  3. Wypisz List[dict]:

    • klucz: nazwa z nagłówka

    • wartość: wyniki pomiarów lub gatunek

  4. Porównaj wyniki z sekcją "Output" (patrz poniżej)

Input
DATA = [
    ('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


result: 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

6.5.9.3. Label encoder

English
  1. Use data from "Input" section (see below)

  2. Define:

    • features: List[tuple] - measurements

    • labels: List[int] - species

    • label_encoder: Dict[int, str] - dictionary with encoded (as numbers) species names

  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 DATA

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

  7. Print features, labels and label_encoder

  8. Compare result with "Output" section (see below)

Polish
  1. Użyj danych z sekcji "Input" (patrz poniżej)

  2. Zdefiniuj:

    • features: List[tuple] - pomiary

    • labels: List[int] - gatunki

    • label_encoder: Dict[int, str] - słownik zakodowanych (jako cyfry) 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 DATA

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

  7. Wypisz feature, labels i label_encoder

  8. Porównaj wyniki z sekcją "Output" (patrz poniżej)

Input
DATA = [
    ('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