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

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

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

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

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

{% hint style="info" %}
Например, в компьютерной игре все экранные объекты могут смещаться на одинаковую величину или в списке чисел к каждому элементу может применяться одна и та же статистическая операция. А может быть, вам потребовалось вывести все заголовки из списка статей на сайте.&#x20;
{% endhint %}

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

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

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

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

for name in students:
    print(name)
```

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

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

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

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

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

```python
for name in students:
```

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

```python
print(name)
```

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

```python
for name in students:
```

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

```python
print(name)
```

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

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

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

```python
for dog in dogs:
    pass

for cat in cats:
    pass

for item in bundle:
    pass
```

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

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

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

```python
```

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

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

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

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

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

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

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

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

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

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

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

{% hint style="info" %}
Например, в компьютерной игре могут храниться координаты каждого персонажа на экране, таблицы рекордов и так далее. В программах визуализации данных пользователь почти всегда работает с наборами чисел: температурой, расстоянием, численностью населения, широтой\долготой и другими числовыми данными.
{% endhint %}

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

### Функция range()

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

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

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

```python
1
2
3
4
```

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

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

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

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

```python
1
2
3
4
5
```

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

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

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

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

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

[1, 2, 3, 4, 5]
```

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

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

[1, 3, 5, 7, 9]
```

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

```python
[2, 4, 6, 8, 10]
```

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

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

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

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

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

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

1
5
15
```

## Цикл while

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

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

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

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

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

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

![](/files/-MJc_ktdKXiYEAUJ-en5)

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

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

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

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

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

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

```python
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()`

```python
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()` позволяет сделать удобным доступ к элемента списка по индексу.

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

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

range(0, 5)
```

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

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

```python
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() генерирует пары кортежей (кортеж - неизменяемый список, он будет рассмотрен позже).

```python
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]
```

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

```python
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`

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

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

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

{% hint style="danger" %}
Внимание! Оператор `break` прерывает выполнение цикла, а не программы, то есть далее будет выполнена инструкция, следующая сразу за циклом
{% endhint %}

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

```python
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
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://opu.gitbook.io/101/sprint-1.-bazovye-znaniya-i-osnovy-programmirovaniya/2.-osnovy-python/komandy-if.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
