Цикл for Python. Основы

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

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

На фото изображено окно программы Python.

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

>>> spisok = [10, 40, 20, 30]
>>> for element in spisok:
… print(element + 2)

12
42
22
32

Переменная element используется после ключевого слова for. Можно использовать любое имя. Часто применяют имя i. При следующей интеграции цикла for, из списка spisok будет использоваться следующий элемент. Идентификатор element будет связан с числом 10 , при первой прокрутке, со второй уже с числом 40, и так далее. После того как элементы закончатся, цикл завершит свою работу.

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

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

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

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

>>> i = 0
>>> for element in spisok:
… spisok[i] = element + 2
… i += 1

>>> spisok
[12, 42, 22, 32]

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

>>> i = 0
>>> while i < len(spisok): … spisok[i] = spisok[i] + 2 # или spisok[i] += 2 … i = i + 1 # или i += 1 … >>> spisok
[14, 44, 24, 34]

Тем более цикл while помог избавиться от переменной element.

Функция range()

Далее нужно рассмотреть функцию range(). «Range» можно перевести как «диапазон». Она имеется свойство принимать несколько аргументов. Их предназначение такое же как у функции randrange() из модуля random.

Генерация чисел от 0 до определенного числа, происходит, если задан только один. От первого до второго, не включая его, генерируются, если заданы два. И соответственно, если заданы три, то третье число будет считаться шагом. Но, главная функция range(), в отличии от randrange(), в указанном диапазоне генерирует не одно число.

Она в принципе не берет в работу случайные числа, только последовательность чисел. Например, range(5, 11) сгенерирует последовательность 5, 6, 7, 8, 9, 10. Но это уже не структура данных типа «список». Это уже объекты своего класса, а именно диапазоны:

>>> 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 «», line 1, in
TypeError: ‘range’ object does not support item assignment

Цикл for и range()

Вместе функция range() и цикл for образуют отличную пару, вот зачем есть необходимость их видеть вместе.

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

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

Len даст нам измерить длину списка. Как видно на примере – это 4. Далее 4 передастся в функцию range(),для генерации последовательности чисел от 0 до 3. Что и является индексами элементов списка.

Далее «соединим» for и range():

>>> for i in range(len(spisok)):
… spisok[i] += 2

>>> spisok
[16, 46, 26, 36]

Элементы берутся из объекта range, в заголовок цикла for. Не упоминается список, элементы сего будут перезаписывать. При данных о длине списка, он будет выглядеть так : for i in range(4). Как же будет использоваться I в теле цикла, вопрос другой.

Примечание! Вместо идентификатора i использоваться может иной.

Функция enumerate()

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

>>> spisok = [16, 46, 26, 36]
>>> for i in enumerate(spisok):
… print(i)

(0, 16)
(1, 46)
(2, 26)
(3, 36)

Можно извлечь индекс и значение в соответствующем теле в структуре рассматриваемого цикла:

>>> for item in enumerate(spisok):
… print(item[0], item[1])

0 16
1 46
2 26
3 36

Но все же обычно используют две переменные перед in, чаще всего в заголовках for:

>>> for id, val in enumerate(spisok):
… print(id, val)

0 16
1 46
2 26
3 36

Для чего нужно использовать range() в заголовке for? Это на самом деле проще! Если не нужны значении , а нужны только индексы.

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

Для возвращения объекта и используется функция range. Он не является итератором, но можно к этому привести. При использовании в заголовке range() и enumerate(), эти объекты теряюится, т.к они не присваиваются переменным и по завершению цикла исчезают. Но можно присвоить им переменные, тогда получится:

>>> r_obj = range(len(spisok))
>>> e_obj = enumerate(spisok)
>>> for i in r_obj:
… if i == 1:
… break

>>> for i in e_obj:
… if i[0] == 1:
… break

>>> for i in r_obj:
… print(i)

0
1
2
3
>>> for i in e_obj:
… print(i)

(2, 26)
(3, 36)

Нужно прервать извлечение элементов из объекта на элементе с индексом 1, после этого прогоняем объекты через цикл for. Но необходимо помнить что для r_obj обход начинается сначала, а в случае e_obj пойдет с того на чем остановился.

При этом e_obj не будет содержать извлеченных ранее элементов.

Итераторы

Итератор — это такая структура данных, которая используется для обращения к определенному элементу, как объект с потоком данных. Когда итератор передается во встроенный метод next(), он возвращает следующее значение из связанного потока данных. Исключение StopIteration возникает когда утрачены все элементы. И для любых последующих вызовов метода next(), он будет вызывать исключение StopIteration.

Интегративными объектами является и интеграторы, однако они поддерживают, согласно протоколу итератора, метод inter() сами по себе. Следовательно, можно получить и сам объект итератора вызовом метода inter().

Там где ожидается интеграция, можно использовать итераторы, как в цикле for. Но нужно помнить, после вызова iter()для объекта-контейнера, новый интегратор будет возвращать каждый раз. Для интегратора вызов inter() будет возвращать тот же объект.

Ссылка на основную публикацию