3. Loops

3.1. while

  • Continue execution when argument is True
while True:
    pass
i = 0

while i <= 10:
    print(i)
    i += 1

3.2. for

3.2.1. Iterating over str

  • Iterating str will get character on each iteration:

    for character in 'setosa':
        print(character)
    
    # s
    # e
    # t
    # o
    # s
    # a
    

3.2.2. Iterating simple collections

  • Iterating over list:

    DATA = [5.1, 3.5, 1.4, 0.2, 'setosa']
    
    for element in DATA:
        print(element)
    
    # 5.1
    # 3.5
    # 1.4
    # 0.2
    # 'setosa'
    
  • Iterating over tuple:

    DATA = (5.1, 3.5, 1.4, 0.2, 'setosa')
    
    for element in DATA:
        print(element)
    
    # 5.1
    # 3.5
    # 1.4
    # 0.2
    # 'setosa'
    
  • Iterating over set:

    DATA = {5.1, 3.5, 1.4, 0.2, 'setosa'}
    
    for element in DATA:
        print(element)
    
    # 5.1
    # 3.5
    # 1.4
    # 0.2
    # 'setosa'
    
  • range(0, 5) will generate (0, 1, 2, 3, 4)

    for number in range(0, 5):
        print(number)
    
    # 0
    # 1
    # 2
    # 3
    # 4
    

3.2.3. Iterating over nested list items

DATA = [
    (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'),
]

for element in DATA:
    print(element)

# (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')
a, b = 'a', 0
a, b = ('a', 0)
key, value = ('a', 0)
DATA = [
    ('a', 0),
    ('b', 1),
    ('c', 2),
]

for key, value in DATA:
    print(f'key: "{key}", value: "{value}"')

# key: "a", value: "0"
# key: "b", value: "1"
# key: "c", value: "2"
DATA = [
    (0, 1),
    ('name', 'José'),
    ('locations', ['CapeCanaveral', 'Houston']),
]

for key, value in DATA:
    print(f'key: "{key}", value: "{value}"')

# key: "0",         value: "1"
# key: "name",      value: "José"
# key: "locations", value: "['CapeCanaveral', 'Houston']"

3.2.4. enumerate()

DATA = [
    (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'),
]

for element in DATA:
    print(element)

# (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')
DATA = [
    (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'),
]

for i, element in enumerate(DATA):
    print(i, element)

# 0 (5.1, 3.5, 1.4, 0.2, 'setosa')
# 1 (5.7, 2.8, 4.1, 1.3, 'versicolor')
# 2 (6.3, 2.9, 5.6, 1.8, 'virginica')

3.2.5. Iterating over dict items

  • dict elements order changes!

  • Iterating over dict values:

    DATA = {
        'Sepal length': 5.1,
        'Sepal width': 3.5,
        'Petal length': 1.4,
        'Petal width': 0.2,
        'Species': 'setosa',
    }
    
    DATA.values()
    # [5.1, 3.5, 1.4, 0.2, 'setosa']
    
    for element in DATA.values():
        print(element)
    
    # 5.1
    # 3.5
    # 1.4
    # 0.2
    # 'setosa'
    
  • Iterating over dict keys:

    DATA = {
        'Sepal length': 5.1,
        'Sepal width': 3.5,
        'Petal length': 1.4,
        'Petal width': 0.2,
        'Species': 'setosa',
    }
    
    DATA.keys()
    # ['Sepal length', 'Sepal width', 'Petal length', 'Petal width', 'Species']
    
    for element in DATA.keys():
        print(element)
    
    # 'Sepal length'
    # 'Sepal width'
    # 'Petal length'
    # 'Petal width'
    # 'Species'
    
  • By default dict iterates over keys:

    DATA = {
        'Sepal length': 5.1,
        'Sepal width': 3.5,
        'Petal length': 1.4,
        'Petal width': 0.2,
        'Species': 'setosa',
    }
    
    DATA.keys()
    # ['Sepal length', 'Sepal width', 'Petal length', 'Petal width', 'Species']
    
    for element in DATA.keys():
        print(element)
    
    # 'Sepal length'
    # 'Sepal width'
    # 'Petal length'
    # 'Petal width'
    # 'Species'
    
  • Getting pair: key, value from dict items:

    DATA = {
        'Sepal length': 5.1,
        'Sepal width': 3.5,
        'Petal length': 1.4,
        'Petal width': 0.2,
        'Species': 'setosa',
    }
    
    DATA.items()
    # [
    #   ('Sepal length', 5.1),
    #   ('Sepal width', 3.5),
    #   ('Petal length', 1.4),
    #   ('Petal width', 0.2),
    #   ('Species', 'setosa')
    # ]
    
    
    for key, value in DATA.items():
        print(f'{key} -> {value}')
    
    # Sepal length -> 5.1
    # Sepal width -> 3.5
    # Petal length -> 1.4
    # Petal width -> 0.2
    # Species -> setosa
    

3.2.6. Iterating complex types

DATA = ['Max', ('1.0', 'José'), 3, 2.8, {True, None, False}]

for element in DATA:
    print(f'value: "{element}"')

# value: "Max"
# value: "('1.0', 'José')"
# value: "3"
# value: "2.8"
# value: "{False, True, None}"
DATA = ['Max', ('1.0', 'José'), 3, 2.8, {True, None, False}]

for element in DATA:
    for sub in element:
        print(f'value: "{sub}"')

# value: "M"
# value: "a"
# value: "x"
# value: "1.0"
# value: "José"
# TypeError: 'int' object is not iterable
DATA = ['Max', ('1.0', 'José'), 3, 2.8, {True, None, False}]

for element in DATA:

    if isinstance(element, (list, set, tuple)):
        for sub in element:
            print(f'value: "{sub}"')
    else:
        print(f'value: "{element}"')

# value: "Max"
# value: "1.0"
# value: "José"
# value: "3"
# value: "2.8"
# value: "False"
# value: "True"
# value: "None"

3.3. Assignments

3.3.1. Text manipulation

  1. Dany jest tekst przemównienia John F. Kennedy’ego “Moon Speech” wygłoszony na Rice Stadium (zdania oddzielone są kropkami)

    We choose to go to the Moon. We choose to go to the Moon in this decade and do the other things. Not because they are easy, but because they are hard. Because that goal will serve to organize and measure the best of our energies and skills. Because that challenge is one that we are willing to accept. One we are unwilling to postpone. And one we intend to win
    
  2. Każde zdanie oczyść z białych znaków na początku i końcu

  3. Policz ile jest wyrazów w każdym zdaniu

  4. Wypisz na ekranie słownik o strukturze:

    • Dict[str, int]
    • klucz: zdanie
    • wartość: ilość wyrazów
  5. Na końcu wypisz także ile jest:

    • zdań
    • słów
    • znaków (łącznie ze spacjami wewnątrz zdań, ale bez kropek)
About:
  • Filename: loop_sentences.py
  • Lines of code to write: 10 lines
  • Estimated time of completion: 10 min
Co zadanie sprawdza:
 
  • Dzielenie stringów
  • Sprawdzanie długości ciągów znaków
  • Iterowanie po elementach listy
  • Nazywanie zmiennych

3.3.2. Unique keys from schema-less database

  1. Mając bazę danych z listingu poniżej
  2. Wygeneruj listę unikalnych kluczy dictów
DATABASE = [
    {'last_name': 'Jiménez'},
    {'first_name': 'Mark', 'last_name': 'Watney'},
    {'first_name': 'Иван', 'age': 42},
    {'first_name': 'Matt', 'last_name': 'Kowalski', 'born': 1961},
    {'first_name': 'José', 'born': 1961, 'agency': 'NASA'},
]
Algorithm:
  1. Iteruj po rekordach w bazie danych
  2. Z rekordu wyciągnij klucze
  3. Dodaj klucze do zbioru
  4. Usuń duplikaty w zbiorze
About:
  • Filename: loop_unique_keys.py
  • Lines of code to write: 5 lines
  • Estimated time of completion: 10 min
The whys and wherefores:
 
  • Generowanie zbiorów
  • Usuwanie powtarzających się elementów
  • Wyciąganie elementów ze słownika
  • Iterowanie po słowniku
  • Aktualizacja zbiorów

3.3.3. Label encoder

  1. Dany jest zbiór pomiarów Irysów Code Listing 3.1.

  2. Ze zbioru wyodrębnij dane odrzucając nagłówek

  3. Z danych wyodrębnij:

    • cechy opisujące: features: List[Tuple[float]]
    • cechy opisywane: labels: List[int]
  4. Przykład danych wyodrębnionych:

    features = [
        (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 = [0, 1, 2, 1, 2, 0, ...]
    
  5. Aby móc odszyfrować labels i zamienić wartości na nazwy gatunków, potrzebny jest słownik podmiany “liczba -> nazwa”

  6. Wygeneruj słownik species: Dict[int, str] na podstawie danych

  7. Przykład słownika species:

    species = {
        0: 'virginica',
        1: 'setosa',
        2: 'versicolor'
    }
    
  8. Wyświetl na ekranie:

    • species
    • labels
    • features
Algorithm:
  1. Wyodrębnij dane odrzucając nagłówek
  2. Stwórz słownik gatunków species
  3. Iteruj po elementach zbioru danych
  4. Gatunek to ostatni element rekordu
  5. Jeżeli w słowniku nie ma gatunku, to dodaj go z kolejnym numerem
  6. Do listy label dodawaj wartość słownika gatunków dla gatunku w tym rekordzie
  7. Odwróć słownik gatunków
  8. Wyświetl na ekranie species oraz labels
About:
  • Filename: loop_label_encoder.py
  • Lines of code to write: 13 lines
  • Estimated time of completion: 15 min
The whys and wherefores:
 
  • Sprawdzanie występowania elementów w słowniku
  • Generowanie słownika i listy na podstawie innych danych
  • Odwracanie słownika
Code Listing 3.1. Sample Iris databases
[
    ('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'),
]