#6 Python для Data Science — объединение цикла for и инструкции if

695

В прошлый раз вы узнали, как работают инструкции if и циклы for в Python. В этот раз стоит поговорить о том, как объединять их. На практических примерах вы узнаете, как совмещать несколько циклов for, а также — один цикл for с инструкцией if.

Это практическое руководство! Желательно повторять те части, где нужно писать код, и решать задачи в конце статьи! Также рекомендуется вернуться к прошлым материалам.

Цикл for внутри цикла for — или просто вложенный цикл for

Чем сложнее проект, над которым ведется работа, тем больше вероятность, что придется работать с вложенным циклом for. Это значит, что будет одна итерация с другой итерацией внутри нее.

Предположим, что есть 9 сериалов в трех категориях: комедии, мультфильмы и драмы. Они представлены во вложенном списке Python («списки в списке»):

my_movies = [['How I Met Your Mother', 'Friends', 'Silicon Valley'],
	    ['Family Guy', 'South Park', 'Rick and Morty'],
	    ['Breaking Bad', 'Game of Thrones', 'The Wire']]

Необходимо посчитать символы в этих названиях и вывести результаты один за одним на экране в таком формате:

"The title [movie_title] is [X] characters long."

Как это можно сделать? Поскольку в основном списке есть три списка, чтобы получить их названия нужно перебрать элементы my_movies. Это нужно сделать и в основном списке, и в каждом вложенном:

for sublist in my_movies:
    for movie_name in sublist:
        char_num = len(movie_name)
        print("The title " + movie_name + " is " + str(char_num) + " characters long.")

Примечание: len() — это функция Python, которая выводит целое число. Чтобы сделать его «выводимым», нужно превратить число в строку. О том, как это сделать, говорилось в прошлом руководстве.

Цикл for внутри цикла for

Циклы for в Python может быть сложно понять вначале, а с вложенными циклами все еще сложнее. Поэтому чтобы разобраться с тем, что происходит, нужно взять ручку и бумагу и попробовать воспроизвести скрипт так, будто вы компьютер — пройти через каждый шаг и выписать результаты.

И еще кое-что:
Синтаксис! Правила те же, что были при изучении простых циклов for. Единственное, на чем важно сделать акцент — отступы. Только используя корректные отступы в Python, вы сможете сообщить языку, в каком именно блоке цикла (внешнем или внутреннем) нужно применить тот или иной код. Попробуйте сделать следующее и обнаружить отличия в этих примерах:

Цикл for внутри цикла for - синтаксис

Инструкции if в цикле for

Внутри цикла for также можно использовать инструкции if.

В качестве примера можно привести известное упражнение, которое предлагают junior-специалистам в сфере data science:

Переберите числа до 99. Выводите «fizz» для каждого числа, которое делится на 3, «buzz» — для тех, что делятся на 5 и «fizzbuzz» — для тех, что делятся на 3 и на 5! Если число не делится, выводите тире (’-’)

Вот решение:

for i in range(100):
    if i % 3 == 0 and i % 5 == 0:
        print('fizzbuzz')
    elif i % 3 == 0:
        print('fizz')
    elif i % 5 == 0:
        print('buzz')
    else:
        print('-')

Как видно в примере, инструкция if в цикле for отлично подходит, чтобы оценить диапазон чисел (или, например, элементы списка) и разбить их по категориям. Таким же образом к ним можно применить функции или просто вывести.

Важно: при использовании инструкции if в цикле for будьте особенно внимательно с отступами, потому что если что-то упустить, то программа работать не будет.

Break

В Python есть удобный инструмент потока, который идеально подходит для управления инструкциями if в циклах for. Это инструкция break.

Найдете первое 7-значное число, которое делится на 137? (Только одно — первое).

Решение:

for i in range(0, 10000000, 137):
    if len(str(i)) == 7:
        print(i)
        break

Этот цикл берет каждое 137-е число (for i in range (0, 10000000, 137)) и проверяет, используется ли в нем 7 цифр или нет (if len(str(i) == 7). Как только он получит первое 7-значное число, инструкция if станет истинной (True), и произойдут две вещи:

  1. print(i) — число выведется на экран
  2. break прервет цикл, чтобы первое 7-значное число было также и последним на экране.

Узнать больше о break (и его брате близнеце, continue) можно в статье: Синтаксис, возможности и подводные камни цикла for Python 3.

Примечание: эту задачу можно решить еще проще с помощью цикла while. Но поскольку руководства по этому циклу еще нет, здесь был использован подход цикл for + break.

Проверьте себя!

Пришло время узнать, насколько вы разобрались с инструкцией if, циклами for и их объединением. Попробуйте решить следующее задание.

Создайте скрипт на Python, который узнает ваш возраст максимум с 8 попыток. Он должен задавать только один вопрос: угадывать возраст (например, «Вам 67 лет?»). Отвечать же можно одним из трех вариантов:

  • correct
  • less
  • more

Основываясь на ответе, компьютер должен делать новые попытки до тех пор, пока не узнает корректный возраст.

Примечание: для решения задачи нужно изучить новую функцию input(). Больше о ней здесь.

Готовы? Вперед!

Решение

Вот код решения.

Примечание: решить задачу можно и с помощью цикла while. Но поскольку он еще не рассматривался, был выбран вариант с for.

down = 0
up = 100
for i in range(1,10):
    guessed_age = int((up + down) / 2)
    answer = input('Are you ' + str(guessed_age) + " years old?")
    if answer == 'correct':
        print("Nice")
        break
    elif answer == 'less':
        up = guessed_age
    elif answer == 'more':
        down = guessed_age
    else:
        print('wrong answer')

Логика решения следующая:

  • Устанавливаем диапазон от 0 до 100, предполагая, что возраст «игрока» будет где-то посередине.
    down = 0  
    up = 100
    
  • Скрипт всегда спрашивает среднее значение диапазона (первой попыткой будет 50):
    guessed_age = int((up + down) / 2)
    answer = input('Are you ' + str(guessed_age) + " years old?")
    
  • После получения ответа от «игрока» могут быть 4 возможных сценария:
    • Если возраст угадан, скрипт заканчивается и возвращает определенный ответ.
    if answer == 'correct':
      print("Nice")
      break
    
    • Если ответ «меньше», тогда цикл начинается сначала, но перед этим максимальное значение диапазона устанавливается на уровне последнего предположения (Так, вторая итерация будет искать середину между 0 и 50).
      elif answer == 'less':
         up = guessed_age
      
    • То же самое для «больше» — только в этом случае меняется минимум:
      elif answer == 'more':
         down = guessed_age
      
    • И в конце обрабатываются ошибки или опечатки:
      else:
          print('wrong answer')
      

Объединение цикла for и инструкции if задача

Итого

Теперь вы знаете о:

  • Вложенных циклах for в Python
  • Объединении циклов for и инструкций if

Это уже не базовый уровень Python, а переход к среднему. Использование этих инструментов предполагает понимание логики Python 3 и постоянной практики.

В серии этих руководств осталось всего два урока. Продолжайте, чтобы узнать все об основах синтаксиса Python.

Тест на знание python

Какая функция разворачивает список задом наперед?
Какой будет результат выполнения этого кода?
Какой будет результат выполнения кода — print(type(1J)) ?
Какой будет результат выполнения этого кода?
Что выведет этот код?