Циклы. Работа со списками

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

Перебор всего списка

Ранее мы научились создавать простые списки и работать с отдельными элементами списков. Очень часто программисту требуется перебрать весь список в нескольких строках кода (независимо от длины списка). Механизм перебора позволяет выполнить одно действие или набор действий с каждым элементом в списке. С его помощью вы сможете эффективно работать со списками любой длины, даже состоящими из тысяч и миллионов элементов.

Типичная задача из области программирования - перебрать все элементы списка и выполнить с каждым элементом одну и ту же операцию.

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

В ситуациях, требующих применения одного действия к каждому элементу списка, можно воспользоваться цикл for.

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

В следующем примере цикл for используется для вывода имен студентов

students = ['Иван', 'Петр', 'Сергей']

for name in students:
    print(name)

В строке 3 определяется цикл for. Эта строка говорит Python взять очередное имя из списка и сохранить его в переменной name. В строке 4 выводится имя, только что сохраненное в name. Затем строки 3 и 4 повторяются для каждого имени в списке. Этот код можно описать так: "Для каждого фокусника в списке вывести его имя". Результат представляет собой простой перечень имен из списка

Иван
Петр
Сергей

Подробнее о циклах

Концепция циклов очень важна, потому что она представляет один из основных способов автоматизации повторяющихся задач компьютером.

Например, в примере выше Python сначала читает первую строку цикла:

for name in students:

Эта строка цикла означает, что нужно взять первое значение из списка studentsи сохранить его в переменной name. Первое значение в списке - 'Иван'. Затем Python читает следующую строку:

print(name)

Python выводит текущее значение name, которое равно 'Иван'. Так как в списке еще остались другие значения, Python возвращается к первой строке цикла:

for name in students:

Python берет следующее значение из списка - 'Петр', и сохраняет его в students. Затем выполняется строка:

print(name)

Python снова выводит значение переменно name, теперь это 'Петр'. Весь цикл повторяется еще раз с последним значением в списке - 'Сергей'. Так как других значений в списке не осталось, Python переходит к следующей строке в программе. В данном случае после цикла for ничего нет, поэтому программа просто завершается.

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

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

for dog in dogs:
    pass

for cat in cats:
    pass

for item in bundle:
    pass

Выполнение этого правила поможет вам проследить за тем, какие действия выполняются с каждым элементом в цикле for.

Более сложные действия в циклах for

В цикле for с каждым элементом списка может выполняться практически любое действие

Тело цикла for может содержать сколько угодно строк кода. Каждая строка с начальным отступом после строки for name in students считается находящейся в цикле и выполняется по одному разу для каждого значения в списке. Таким образом, с каждым значением в списке можно выполнить любые операции на ваше усмотрение. На практике часто требуется выполнить в цикле for несколько разных операций для каждого элемента списка.

Выполнение действий после цикла for

Что происходит после завершения цикла for? Обычно программа выводит некую сводную информацию или переходит к другим операциям.

Каждая строка кода после цикла for, не имеющая отступа, выполняется без повторения.

students = ['Иван', 'Петр', 'Сергей']

for name in students:
    print("Студент " + name)

print("Вы зачислены на бюджет")

Первая функция print() выполняется по одному разу для каждого элемента из списка студентов. Функция print() в строке 6 отступа не имеет, это сообщение выводится только один раз.

Студент Иван
Студент Петр
Студент Сергей
Вы зачислены на бюджет

Создание числовых списков

Необходимость хранения наборов чисел возникает в программах по многим причинам.

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

Списки идеально подходят для хранения наборов чисел, а Python предоставляет специальные средства для эффективной работы с числовыми списками. Достаточно один раз понять, как эффективно пользоваться этими средствами, и ваш код будет хорошо работать даже в том случае, если список содержит миллионы элементов.

Функция range()

Функция range() упрощает построение числовых последовательностей. Например, с ее помощью можно легко вывести серию чисел:

for value in range(1, 5):
    print(value)

И хотя на первый взгляд может показаться, что он должен вывести числа от 1 до 5, на самом деле число 5 не выводится:

1
2
3
4

В этом примере функция range() выводит только числа от 1 до 4. Перед вами еще один пример явления "смещения на 1", которое часто встречается в языках программирования. При выполнении функции range() Python начинает отсчет от первого переданного значения и прекращает его при достижении второго. Так как на втором значении происходит остановка, конец интервала (в данном случае 5) не встречается в выводе в консоль.

Чтобы вывести числа от 1 до 5, используйте вызов range(1, 6):

for value in range(1, 6):
    print(value)

На этот раз вывод начинается с 1 и завершается 5

1
2
3
4
5

При вызове range() также можно передать только один аргумент. В этом случае последовательность чисел будет начинаться с 0. Например, range(6) вернет числа от 0 до 5.

for value in range(6):
    print(value)
    
0
1
2
3
4
5

Использование range() для создания числового списка

Если вы хотите создать числовой список, преобразуйте результаты range() в список с помощью функции list(). Если заключить вызов range() в list(), то результат будет представлять собой список с числовыми элементами.

numbers = list(range(1,6))
print(numbers)

[1, 2, 3, 4, 5]

Функция range() также может генерировать числовые последовательности, пропуская числа в заданном диапазоне. Например, построение списка четных чисел от 1 до 10 происходит следующим образом

numbers = list(range(1,11,2))
print(numbers)

[1, 3, 5, 7, 9]

В этом примере функция range() начинает со значения 2, а затем увеличивает его на 2. Приращение 2 последовательно применяется до тех пор, пока не будет достигнуто или пройдено конечное значение 11, после чего выводится результат

[2, 4, 6, 8, 10]

С помощью функции range() можно создать практически любой диапазон чисел. Например, как бы вы создали список квадратов всех целых чисел от 1 до 10? Один из возможных вариантов выглядит так

squares = []
for value in range(1, 11):
    squares.append(value ** 2)
    
print(squares)

[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

Некоторые функции работы со списками

Некоторые функции Python предназначены для работы с числовыми списками. Например, вы можете легко узнать минимум, максимум и сумму числового списка

digits = [1, 2, 3, 4, 5]
print(min(digits))
print(max(digits))
print(sum(digits))

1
5
15

Цикл while

While переводится с английского как "пока", в смысле "пока имеет это, делаем то".

Можно сказать, что while является универсальным циклом. Он присутствует во всех языках, поддерживающих структурное программирование, в том числе и в Python. Его синтаксис можно выразить так:

while логическое_выражение:
    выражение 1;

    выражение n;

Это похоже на условный оператор if. Однако в случае циклических операторов их тела могут выполняться многократно. В случае if, если логическое выражение в заголовке возвращает истину, то тело выполняется единожды. После этого поток выполнения программы возвращается в основную ветку и выполняет следующие выражения, расположенные ниже всей конструкции условного оператора.

В случае while, после того как его тело выполнено, поток возвращается к заголовку цикла и снова выполняет условие. Если логическое выражение возвращает истину, то тело снова выполняется. Потом снова возвращаемся к заголовку и так далее.

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

С циклом while возможны две исключительные ситуации:

  • если при первом заходе в цикл логическое выражение возвращает False, то тело цикла не выполняется ни разу. Эту ситуацию можно считать нормальной, так как при определенных условиях логика программы может предполагать отсутствие необходимости к выполнении выражений тела цикла;

  • если логическое выражение в заголовке while никогда не возвращает False, а всегда остается равным True, то цикл никогда не завершится, если только в его теле нет оператора принудительного выхода из цикла (break) или вызовов функций выхода из программы - quit() или exit() в случае Python. Если цикл повторяется и повторяется бесконечное количество раз, то в программе происходит зацикливание (программа входит в бесконечный цикл) - программа не может завершится и бесконечно повторяет тело цикла.

Самое главное для цикла while - чтобы в его теле происходили изменения значений переменных, которые проверяются в его заголовке, и чтобы хоть когда-нибудь наступил случай, когда логическое выражение в заголовке возвращает False. Иначе произойдет зацикливание.

Циклы с использованием счетчика цикла

Очень часто при использовании циклов и списков бывает необходимость изменить значения в списке или еще по каким-то причинам получить доступ к элементам списка через индекс.

Переменная, которая контролирует повторы выполнения циклов называется счетчик цикла.

digits = [1, 2, 3, 4, 5]

print("Before: ", digits)

i = 0
for el in digits:
    digits[i] = el * 2
    i = i + 1
    
print("After: ", digits)

Before:  [1, 2, 3, 4, 5]
After:  [2, 4, 6, 8, 10]

Это не самая удобная конструкция для обращения к элементу цикла. Если мы знаем длину списка, мы можем использовать цикл while. Длину списка можно получить с помощью встроенной функции len()

digits = [1, 2, 3, 4, 5]

print("Before: ", digits)

i = 0
while i < len(digits):
    digits[i] = digits[i] * 2
    i = i + 1

    
print("After: ", digits)

Before:  [1, 2, 3, 4, 5]
After:  [2, 4, 6, 8, 10]

Использование range() и цикла for

Сочетание цикла for и функции range() позволяет сделать удобным доступ к элемента списка по индексу.

digits = [1, 2, 3, 4, 5]

a = range(len(digits))
print(a)

range(0, 5)

С помощью функции len() измеряется длина списка. В данном случае она равна 5. После этого числа 5 передается в функцию range() и она генерирует последовательность чисел от 0 до 4 включительно. Это как раз индексы элементов нашего списка.

Используем этот принцип совместно с циклом for

digits = [1, 2, 3, 4, 5]

print("Before: ", digits)

for i in range(len(digits)):
    digits[i] = digits[i] * 2
    
print("After: ", digits)

Before:  [1, 2, 3, 4, 5]
After:  [2, 4, 6, 8, 10]

Функция enumerate()

В Python есть еще одна встроенная функция, которая часто используется в заголовке for. Это функция enumerate(). Если range() позволяет получить только индексы элементов списка, то enumerate() генерирует пары кортежей (кортеж - неизменяемый список, он будет рассмотрен позже).

digits = [10, 20, 30, 40, 50]

print("Before: ", digits)

for i in enumerate(digits):
    digits[i[0]] = i[1] * 2
    print("Индекс: " + str(i[0]) + ", значение: " + str(i[1]))
    
print("After: ", digits)

Before:  [10, 20, 30, 40, 50]
Индекс: 0, значение: 10
Индекс: 1, значение: 20
Индекс: 2, значение: 30
Индекс: 3, значение: 40
Индекс: 4, значение: 50
After:  [20, 40, 60, 80, 100]

Чтобы не возиться с индексами, удобнее использовать следующую форму записи

digits = [10, 20, 30, 40, 50]

print("Before: ", digits)

for index, value in enumerate(digits):
    digits[index] = value * 2
    print("Индекс: " + str(index) + ", значение: " + str(value))
    
print("After: ", digits)

Операторы continue и break

Оператор continue позволяет перейти к следующей итерации цикла до завершения выполнения всех инструкций внутри цикла. В качестве примера, выведем на экран все нечетные числа в диапазоне от 0 до 20

for i in range(20):
    if i % 2 == 0:
        continue
    
    print(i)

Оператор break позволяет прервать выполнение цикла досрочно.

# Выводим числа, пока не найдем число, которое
# делится на 7 без остатка
for i in range(1, 20):
    if i % 7 == 0:
        break
    
    print(i)
    
1
2
3
4
5
6

Внимание! Оператор break прерывает выполнение цикла, а не программы, то есть далее будет выполнена инструкция, следующая сразу за циклом

Цикл while совместно с оператором break удобно использовать для работы с вводом из консоли. К примеру, напишем небольшую программу, которая считывает числа, которые ввел пользователь. Для окончания ввода пользователь должен ввести 0. После окончания ввода, программа выдает сумму введенных чисел.

print("Программа суммирует введенные числа. Введите 0 для окончания ввода и"
       " получения суммы чисел")
sum = 0

while True:
    i = input("Введите число: ")
    i = int(i)
    
    if i == 0:
        break;
    
    sum = sum + i
    
print ("Сумма введенных чисел: ", sum)

Программа суммирует введенные числа. Введите 0 для окончания ввода
 и получения суммы чисел

Введите число: 10

Введите число: 20

Введите число: 30

Введите число: 0
Сумма введенных чисел:  60

Last updated