НОЧУ ДПО "Национальный открытый университет "ИНТУИТ"
Опубликован: 24.01.2021 | Доступ: свободный | Студентов: 1229 / 21 | Длительность: 03:57:00
Лекция 12:

Операторы цикла while, for

< Лекция 1 || Лекция 12

Смотреть на youtube

В язык Python включены два привычных оператора цикла - while и for.

Оператор while

Универсальный оператор цикла while имеет привычный для программистов синтаксис:

Init
while <выражение>:
	<операторы>
else:
	<операторы>

Семантика привычна, - пока истинно выражение while, выполняются операторы тела цикла.

Синтаксическая экзотика этого оператора состоит в том, что в оператор while можно добавить ветвь else, которая выполняется тогда, когда while выражение, задающее условие окончания цикла, становится ложным. Эти действия не будут выполняться, если выход из цикла осуществляется оператором break. Польза от этой конструкции невелика. Если необходимо проверять, как закончился цикл, то лучше это делать явно.

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

Рассмотрим задачу поиска в списке элемента с заданными свойствами.

Пример:

def test1():
    #В списке найти элемент с заданными условиями:
    #нечетный элемент больше 8
    i = 0
    s = [3, 6, 7, 8, 9, 14, 15]
    n = len(s)
    while i < n and (s[i] % 2 == 0 or s[i] < 8):
        i += 1
    if i < n:
        item = s[i]
        print('поиск успешен: ', 'элемент = ', item)
    else:
        print("требуемый элемент не найден")
test1()

Результат:


Оператор for

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

for <item> in <collection>:
	 <операторы>

В таком варианте семантика оператора понятна. На каждом шаге цикла элемент item получает значение очередного элемента коллекции. Цикл завершается при исчерпании коллекции.

Синтаксически в цикл for, как и в цикл while, можно добавлять else ветвь.

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

def test2():
    #циклы
    #Формирование  списка (массива) со случайными значениями элементов 
    import random
    mas = []
    n = input("Введите n - размер массива\n")
    n = int(n)
    i =0
    while i < n:
        mas.append(random.randint(-100,100))
        i +=1
    print(mas)
    #сумма элементов
    sum =0
    for item in mas:
        sum +=item
    print('sum = ', sum)  
test2()  

Результаты работы:


Метод range

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

def test3():
    #цикл for и метод range
    #Формирование списка (массива) со случайными значениями элементов 
    import random
    mas = []
    n = input("Введите n - размер массива\n")
    n = int(n)
    for i in range(n):
        mas.append(random.randint(-100,100))        
    print(mas)
    #сумма элементов
    sum =0
    for i in range(n):
        sum +=mas[i]
    print('sum = ', sum)  
test3()

Результаты работы:


Метод range с одним параметром n задает коллекцию индексов, представляющую отрезок натурального ряда чисел от нуля до n - 1.

Метод range может иметь два параметра - m и n. Первый из них задает начало отрезка натуральных чисел (включительно), второй - конец отрезка (исключительно).

Наконец, метод range может включать третий параметр - p, задающий шаг вычисления индекса, что позволяет в полной мере реализовать классический for, изменяющий индексы в пределах от m до n с шагом p.

Рассмотрим пример:

def test4():
    #цикл for с шагом
    sum = 0
    for i in range(10, 15, 2):
        sum += i
    print ("Sum i from 10 to 15 step 2 = ", sum) 
test4()

Результаты работы:


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

В теле цикла может встречаться оператор break, выполнение которого завершает цикл. Как правило, этот оператор входит в if- ветвь оператора if. Ситуация, в которой полезно использовать дополнительный выход из цикла, достаточно часто встречается, например, в задачах поиска по образцу. Рассмотрим пример:

def test5():
    #линейный поиск в списке (массиве mas)
    import random
    mas = []
    n = input("Введите n - размер массива\n")
    n = int(n)
    for i in range(n):
        mas.append(random.randint(-10,10))        
    print(mas)
    pattern = random.randint(-5,5)
    print ("pattern = ", pattern)
    for i in range(n):
        if mas[i] == pattern:
            print("C образцом совпадает элемент массива с индексом ", i)
            break
    if mas[i] != pattern:
        print("в массиве нет элементов, совпадающих с образцом ")
test5()

Результаты работы:


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

def test6():
    #оператор continue. Вычисление суммы и минимального нечетного элемента
    mas = [5, 12, 3, 6, 14]
    sum = 0
    min = 0
    first = True
    n = len(mas)
    for i in range(n):
        sum += mas[i]
        if mas[i] % 2 == 0: continue
        if first : 
            min = mas[i]
            first = False
        else:
            if mas[i] < min:
                min = mas[i]
    print("sum = ", sum)
    if min == 0:
        print (" в массиве нет нечетных элементов")
    else:
        print("нечетный минимальный элемент = ", min)
test6()

Результаты работы:


Дополнительные возможности оператора for

Учитывая большое число разнообразных коллекций, встроенных в язык, основным видом цикла, позволяющим эффективно перебрать все элементы коллекции, является цикл for в форме:

 for <item> in <collection>:
 <операторы>

Примеров подобного использования оператора for было достаточно много. Однако оператор for может применяться и в более сложных ситуациях. Существует форма оператора for, в которой используется не один элемент item, а кортеж элементов. Естественно, в этом случае используется и кортеж коллекций элементов. Семантика оператора for такова - выполняется параллельное итерирование каждой из коллекций. Для создания кортежа коллекций используется функция zip.

Синтаксис оператора for в этом случае таков:

for <item_1>, …<item_k> in zip(<collection_1>, …<collection_k>): 
	<операторы>

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

Рассмотрим пример:

def test7():
    #for - дополнительные свойства - параллельное итерирование
    dict = {'one': 1, 'two': 2, 'three' : 3 }
    str = "five"
    list = [4, 5, 6, 7, 8]
    cort = ("book", "key", "root", "pen")
    set = {11, 13, 17, 19}
    
    for x, y, z, u, v in zip(dict, str, list, cort, set):
        print ('x =', x, ' y = ', y, ' z = ', z,
               'u = ', u, 'v = ', v)
test7()

Результаты работы:


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

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

Рассмотрим пример работы цикла for для чтения строк текстового файла:

def test8():
    print("чтение файла в операторе for")
    print()
    for line in open("Gamlet.txt"):
        print (line, end = '')
    print()
test8()

Результаты работы:


Оператор for может использоваться как часть генератора списков. Пусть у нас есть некоторая коллекция или итерируемый объект, например, файл. Наша задача - создать список, отобрав из коллекции (файла) некоторые элементы, удовлетворяющие определенному условию. В языке Python эта задача эффективно решается благодаря конструкции генератора списка, содержащей оператор for. Поясним синтаксис и семантику генератора списка на примере. Пусть из текстового файла, рассмотренного в предыдущем примере, нужно отобрать строки, содержащие подстроку "Я ", и создать список таких строк.

Рассмотрим вначале классическое решение этой задачи, когда оператор цикла for используется в обычном режиме. Далее приведем более эффективное решение, когда оператор for является частью оператора присваивания. В присваивание включается и условие if для отбора элементов при создании списка.

Пример:

def test9():
    # стандартный способ генерирования списка
    lines = []
    for line in open("Gamlet.txt"):
        if 'Я 'in line:
            lines.append(line)
    print (lines)
    # for встроенный  в оператор присваивания
    lines = [line  for line in open("Gamlet.txt") if 'Я ' in line  ]
    print (lines)
test9()

Результаты работы этих двух вариантов генерации списка:

Как работает достаточно общая конструкция генератора некоторой структуры данных легко понять на данном примере. Мы хотим сгенерировать список элементов, отобрав нужные элементы из некоторой коллекции. В данном случае генерируется список lines, элементами которого являются строки line. Оператор for проходит по коллекции, в данном случае по файлу, получая строку за строкой, конструкция if фильтрует эти строки, отбирая строки с нужным свойством. Синтаксически все эти элементы становятся частью выражения в операторе присваивания. Ранее мы познакомились с условным выражением, которое можно использовать в операторе присваивания, что позволяет сокращать число строк текста. Теперь мы познакомились с более экзотической конструкцией - for выражением, которое также можно использовать в операторе присваивания, сокращая число строк текста.

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

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

< Лекция 1 || Лекция 12
Елена Лаптева
Елена Лаптева

Думаю. что не смогу его закончить. Хотелось предупредить других - не тратьте зря время, ищите другой курс.

Михаил Сидоров
Михаил Сидоров

Если S - последовательность, то срез задается как S(i : j) и содержит j - i элементов,

а в примере используютс другие скобки - 

NL[1:3] = ["решили", "не", "искать"]

или это не срез, тогда, что это?