Цикл for в Python. Перебор и изменение элементов списка

Цикл for в языке программирования Python предназначен для перебора элементов структур данных и других составных объектов. Это не цикл со счетчиком, каковым является for во многих других языках.

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

>>> numbers = [10, 40, 20, 30]
>>> for item in numbers:
...     print(item + 2)
...
12
42
22
32

После ключевого слова for используется переменная под именем item. Имя здесь может быть любым. Нередко используют i. На каждой итерации цикла for ей будет присвоен очередной элемент из списка numbers. Так при первой прокрутке цикла идентификатор item связан с числом 10, на второй – с числом 40, и так далее. Когда элементы в numbers заканчиваются, цикл for завершает свою работу.

С английского "for" переводится как "для", "in" как "в". Перевести конструкцию с языка программирования на человеческий можно так: для каждого элемента в списке делать следующее (то, что в теле цикла).

В примере мы увеличивали каждый элемент на 2 и выводили его на экран. При этом сам список конечно же не изменялся:

>>> numbers
[10, 40, 20, 30]

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

>>> i = 0
>>> for item in numbers:
...     numbers[i] = item + 2
...     i += 1
...
>>> numbers
[12, 42, 22, 32]

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

>>> i = 0
>>> while i < len(numbers):
...     numbers[i] = numbers[i] + 2
...     i += 1
...
>>> numbers
[14, 44, 24, 34]

Кроме того, с циклом while мы избавились от переменной item.

Функция range()

Теперь пришло время познакомиться со встроенной в Python функцией range(). "Range" переводится как "диапазон". Она может принимать один, два или три аргумента. Их назначение такое же как у функции randrange() из модуля random. Если задан только один, то генерируются числа от 0 до указанного числа, не включая его. Если заданы два, то числа генерируются от первого до второго, не включая его. Если заданы три, то третье число – это шаг.

Однако, в отличие от randrange(), функция range() генерирует не одно случайное число в указанном диапазоне. Она вообще не генерирует случайные числа. Она создает последовательность чисел в указанном диапазоне. Так, range(5, 11) сгенерирует последовательность 5, 6, 7, 8, 9, 10. Однако это будет не список. Функция range() производит объекты своего класса – диапазоны:

>>> a = range(-10, 10)
>>> a
range(-10, 10)
>>> type(a)
<class 'range'>

Несмотря на то, что мы не видим последовательности чисел, она есть, и мы можем обращаться к ее элементам:

>>> a[0]
-10
>>> a[5]
-5
>>> a[15]
5
>>> a[-1]
9

Хотя изменять их нельзя, так как, в отличие от списков, объекты range() относятся к группе неизменяемых:

>>> a[10] = 100
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'range' object does not support item assignment

Цикл for и range()

Итак, зачем нам понадобилась функций range() в теме про цикл for? Дело в том, что вместе они образуют неплохой тандем. For как цикл перебора элементов, в отличие от while, позволяет не следить за тем, достигнут ли конец структуры. Не надо вводить счетчик для этого, изменять его и проверять условие в заголовке. С другой стороны, range() дает последовательность целых чисел, которые можно использовать как индексы для элементов того же списка.

>>> range(len(numbers))
range(0, 4)

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

Теперь "соединим" for и range():

>>> numbers = [14, 44, 24, 34]
>>> for i in range(len(numbers)):
...     numbers[i] += 2
...
>>> numbers
[16, 46, 26, 36]

Еще раз обратим внимание, в заголовке цикла for берутся элементы вовсе не списка, а объекта range.

Практическая работа

  1. Заполните список случайными числами. Используйте в коде цикл for, функции range() и randint().

  2. Если объект range (диапазон) передать встроенной в Python функции list(), то она преобразует его к списку. Создайте таким образом список с элементами от 0 до 100 и шагом 17.

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

  4. Напишите программу, которая заполняет список пятью словами, введенными с клавиатуры, измеряет длину каждого слова и добавляет полученное значение в другой список. Например, список слов – ['yes', 'no', 'maybe', 'ok', 'what'], список длин – [3, 2, 5, 2, 4]. Оба списка должны выводиться на экран.

Примеры решения и дополнительные уроки в pdf-версии курса


Python. Введение в программирование




Все разделы сайта