Циклы

При написании программ часто возникает потребность делать одно и то же действие для нескольких объектов. Например, сохранить 5 пользователей:

user1.save()
user2.save()
user3.save()
user4.save()
user5.save()

Кода пока не очень много, но что будет, когда пользователей будет 20? А что если нужно обработать 3 миллиона пользователей вашего сайта? Помогут циклы.

Цикл — это запуск одного и того же кода для каждого элемента в списке. Вот как выглядит пример выше с импользованием списка и циклов:

users = [user1, user2, user3, user4, user5]
for user in users:
  user.save()

Каждый элемент списка users по очереди подставится в переменную user и для него запустится код с отступом.

Что, всё ещё копипастить пользователей в список? Нет, чаще всего такое не требуется и код выглядит так:

users = get_users_from_database()  # возвращает список всех пользователей
for user in users:
  user.do_something()  # работа с каждым пользователем по очереди
  user.save()

Снова, каждый пользователь по очереди попадёт в переменную user, у него вызовется метод .do_something(), а затем метод .save().

А если у меня не список, а словарь?

Словарь очень легко можно превратить в 2 списка:

capitals = {
  "Russia": "Moscow",
  "England": "London",
  "China": "Beijing",
  "Italy": "Rome"
}

Первый список — ключи словаря (первые элементы в парах):

print(capitals.keys())
# ['Russia', 'England', 'China', 'Italy']

Второй список — значения (вторые элементы в парах):

print(capitals.values())
# ['Moscow', 'London', 'Beijing', 'Rome']

По умолчанию, если передать в for словарь, он начнёт перебирать ключи:

for country in capitals:
  print(country)
# Russia
# England
# China
# Italy

Но так же через ключи словаря можно добраться и до значений:

for country in capitals:
  capital = capitals[country]
  print("столица {} это {}".format(country,capital))
# столица Russia это Moscow
# столица England это London
# столица China это Beijing
# столица Italy это Rome

В Python есть ещё один способ добраться до значений словаря, использовать .items():

for country, capital in capitals.items():
  print("столица {} это {}".format(country,capital))
# столица Russia это Moscow
# столица England это London
# столица China это Beijing
# столица Italy это Rome

Выполнить код несколько раз

Что, если нужно выполнить код заранее известное количество раз? например, сгенерировать 10 случайных чисел и вывести на экран? По какому такому списку мне перебиать элементы?

В таком случаевыручает функция range().

Что она делает проще показать на примерах:

  • range(5) — вернёт список из 5 элементов, начинаяс нуля: [0, 1, 2, 3, 4]
  • range(2,10) — вернёт список из элементов от 2 до 10: [2, 3, 4, 5, 6, 7, 8, 9]
  • range(2,10,3) — вернёт список из каждого третьего элемента от 2 до 10: [2, 5, 8]

Теперь, научившись генерировать списки нужной длины, можно сгенерировать 10 случайных чисел:

import random

for number in range(10):
  print(random.randint(1,100))

В терминал выведется 10 случайных чисел от 1 до 100. Работает так же, как и ранее: range(10) — это список с числами от 0 до 9. Они по очереди подставятся в переменную number, но ни на что не повлияют, т.к. в коде "внутри for" переменная number не используется.

Строка — тоже список

Python запросто переводит одни типы данных в другие. Он может притвориться, что строка — это список из её символов:

text = "Девман"
for letter in text:
  print(letter)
# Д
# е
# в
# м
# а
# н

Можно превратить строку в список более явно с помощью функции list():

text = "Девман"
my_list = list(text)
print(my_list)
# ['Д', 'е', 'в', 'м', 'а', 'н']