Последовательности

range

Чтобы повторить действия пишут циклы.

Операторы внутри цикла (что нужно повторить) пишут с отступом.

4 раза напечатать Hello:

for x in range(4):
    print('Hello')
# Output:
# Hello
# Hello
# Hello
# Hello

for переменная in последовательность : - это оператор python, который перебирает по 1 элементу из последовательности и записывает ее в переменную.

x - имя переменной. Может быть любое.

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

Не забудьте поставить двоеточие :

for x in range(4):
    print(x)

# Output:
# 0
# 1
# 2
# 3

range(4) вернет последовательность из 0, 1, 2, 3. То есть 4 целых числа, от 0 (включая) до 4 (не включая).

Чтобы напечатать эти числа в 1 строку, будем ставить после каждого числа пробел. В функции print укажем end=' ' (в конце ставить пробел, а не символ новой строки, как обычно).

for x in range(4):      # переменная х равна по очереди 0 1 2 3
    print(x, end=' ')   # печатаем значение х и пробел
print()                 # ПОСЛЕ цикла 1 раз печатаем \n (символ новой строки)
# Output:
# 0 1 2 3

Функция range(3, 10) вернет последовательность чисел от 3 (включая) до 10 (НЕ включая):

for x in range(3, 10):  # переменная х равна по очереди 3 4 5 6 7 8 9
    print(x, end=' ')   # печатаем значение х и пробел
print()                 # печатаем символ новой строки \n

# Output:
# 3 4 5 6 7 8 9

Третий аргумент функции range - на сколько увеличить число: Функция range(3, 10, 2) вернет последовательность чисел от 3 (включая) до 10 (НЕ включая) +2 каждый раз:

for x in range(3, 10, 2):  # переменная х равна по очереди 3 5 7 9
    print(x, end=' ')      # печатаем значение х и пробел
print()                    # печатаем символ новой строки \n

# Output:
# 3 5 7 9

читаем и печатаем много чисел

Даны 2 целых числа. 1 число на 1 строке. Нужно прочитать эти числа и напечатать их.

x = int(input())    # читаем первую строку, преобразуем ее к целому числу
y = int(input())    # читаем вторую строку, преобразуем ее к целому числу

print(x)            # печатаем число
print(y)            # печатаем число

# Input:
# 3
# 5
# Output:
# 3
# 5

Если числа заданы на одной строке через пробел, то их читаем так:

x, y = map(int, input().split())
print(x)
print(y)

# Input:
# 3 5
# Output:
# 3
# 5

Похоже можно прочитать много чисел на строке через пробел:

a = map(int, input().split())
for x in a:
    print(x)

# Input:
# 3 5 -2 7 1
# Output:
# 3
# 5
# -2
# 7
# 1

Разберем этот код:

  • input() - прочитать строку '3 5 -2 7 1'
  • input().split() - разбить прочитанную строку по пробельным символам на строки, получится список строк; ['3', '5', '-2', '7', '1']
  • map(функция, последовательность) - применить функцию к каждому элементу последовательности, вернуть полученную последовательность. Тут получили последовательность чисел 3 5 -2 7 1. Переменная a ссылается на эту последовательность.

К полученной последовательности можно применить оператор for..in

Генераторы - 1 раз

Генераторы - это последовательности, по которым можно пройти только один раз.

a = map(int, input().split())
for x in a:     # первый цикл по map
    print(x)
print('---')    # печатаем --- чтобы отделить данные первого цикла от второго
for x in a:     # второй цикл по той же map, map теперь пустая
    print(x)

# Input:
# 3 5 -2
# Output:
# 3
# 5
# -2
# ---

Если нужно будет пройти по тем же данным несколько раз, их нужно сохранить в памяти. Например, сделать из последовательности map список list.

a = list(map(int, input().split()))
for x in a:     # первый цикл по списку list
    print(x)
print('---')    # печатаем --- чтобы отделить данные первого цикла от второго
for x in a:     # второй цикл по тому же списку 
    print(x)

# Input:
# 3 5 -2
# Output:
# 3
# 5
# -2
# ---  
# 3
# 5
# -2

:question: Зачем нужны последовательности map? Давайте сразу из map делать list.

Список хранит все свои элементы в памяти. Элементы последовательности могут вычисляться только тогда, когда потребуются ("ленивые вычисления") и не занимать место в памяти. Полезно, если элементов очень много.

Еще один пример последовательностей, которые хранятся полностью в памяти - строки.

a = 'Hello'
for x in a:     # первый цикл по строке 'Hello'
    print(x)
print('---')    # печатаем --- чтобы отделить данные первого цикла от второго
for x in a:     # второй цикл по той же строке
    print(x)

# Output:
# H
# e
# e
# l
# o
# ---  
# H
# e
# e
# l
# o

Однопроходные алгоритмы

Рассмотрим простые алгоритмы, которые в 1 проход по последовательности чисел вычисляют то, что требуется в задаче.

Сумма

Дано несколько целых чисел на 1 строке через пробел. Найти сумму этих чисел.

Сумму можно найти в один проход по последовательности чисел.

Рассмотрим более простую задачу: найдем сумму чисел 3, 7, -2:

x, y, z = 3, 7, -2
res = x + y + z
print(res)

Если чисел много, то трудно придумывать имена переменных для каждого числа. Перепишем этот код так, чтобы использовать только 2 переменных. res - сумма, x - очередное слагаемое (а не первое слагаемое).

res = 0                     # сначала сумма 0

x = 3
res += x
print('x=', x, 'res=', res) # x= 3 res= 3

x = 7
res += x
print('x=', x, 'res=', res) # x= 7 res= 10

x = -2
res += x
print('x=', x, 'res=', res) # x= -2 res= 8

print(res)                  # 8 - печатаем ответ задачи

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

Код, который делаем 1 раз, пишем или до или после цикла.

Будем вводить числа с клавиатуры. Все числа на 1 строке через пробел.

a = map(int, input().split())

res = 0                         # до цикла сумма равна 0
for x in a:
    res += x
    print('x=', x, 'res=', res)
print(res)                      # после окончания цикла печатаем ответ

Заметьте, этот код находит сумму любого количества чисел в строке, а не только 3 чисел.

Как мы придумали такой алгоритм?

Представим, что мы уже посчитали сумму последовательности чисел и она хранится в res. Если к последовательности добавить еще одно число (запишем его в x), то сумма всех чисел станет res = res + x. То есть на каждом шаге цикла нужно прочитать еще одно число и добавить его к сумме.

Чему должны быть равны значения переменных ДО цикла? Представим, что чисел еще нет. Тогда их сумма 0. x до цикла нам не нужен (чисел нет). res до цикла 0.

Запишем этот алгоритм как функцию mysum от последовательности. Функция будет возвращать сумму чисел.

def mysum(a):                    # создаем функцию mysum
    res = 0
    for x in a:
        res = res + x
        print('x=', x, 'res=', res)
    return res
                                # конец функции mysum
a = map(int, input().split())   # читаем числа с клавиатуры
print('Сумма равна', mysum(a))  # вызываем функцию mysum

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

def mysum(a):                    # создаем функцию mysum
    res = 0
    for x in a:
        res = res + x
        print('x=', x, 'res=', res)
    return res
                                # конец функции mysum
a = [3, 7, -2.5, 0.16]          # зададим последователность как список чиселё
print('Сумма равна', mysum(a))  # вызываем функцию mysum для этого списка
# Output:
# x= 3 res= 3
# x= 7 res= 10
# x= -2.5 res= 7.5
# x= 0.16 res= 7.66
# Сумма равна 7.66

Максимум

Дана последовательность чисел. Найдем максимальное число.

Сначала напишем функцию max2(x, y), которая из двух чисел возвращает максимальное.

def max2(x, y):
    if x > y:
        return x
    else:
        return y

Будем думать как в алгоритме с суммой.

Пусть мы нашли максимальное число для последовательности и сохранили его в res. Нам дали еще одно число в переменной x. Тогда максимум из всех чисел - это максимум из res и x. То есть max2(res, x).

def max2(x, y):                 # функция max2 - максимум из 2 чисел
    if x > y:
        return x
    else:
        return y

def mymax(a):                    # функция mymax - максимум в последовательности а
    res = 0
    for x in a:
        res = max2(res, x)       # раньше при добавлении числа в последовательность 
                                 # его надо было добавить к сумме,
                                 # теперь нужно найти максимум из нового числа и максимума предыдущих чисел
        print('x=', x, 'res=', res)
    return res

a = map(int, input().split())    # читаем числа с клавиатуры
print('Максимум равен', mymax(a)) # вызываем функцию mymax

Проверяем, как работает программа:

# Input:
# 3 -7 12 0
# Output:
# x= 3 res= 3
# x= -7 res= 3
# x= 12 res= 12
# x= 0 res= 12
# Максимум равен 12

Проверим еще раз на последовательности отрицательных чисел.

# Input:
# -3 -7 -2 -10
# Output:
# x= -3 res=0
# x= -7 res=0
# x= -2 res=0
# x= -10 res=0
# Максимум равен 0

Программа работает неправильно. Максимум из отрицательных чисел не может быть 0.

Мы не подумали, чему равен максимум, если чисел нет или оно одно. Если чисел еще нет, то сумма 0, если задано одно число, то сумма равна этому числу.

Если числа не заданы. Максимума у последовательности нет. А у нас в коде написано res = 0. Ошибка.

Если задано одно число, то это число - миниумум.

Надо научиться писать значение "не число" или брать из последовательности первый элемент.

None - значение, которого нет

В Python есть специальное значение None - "этого значения нет".

Посмотрим в интерпретаторе, как раборать с None:

>>> x = None
>>> x
>>> print(x)
None
>>> type(x)
<class 'NoneType'>
>>> x is None
True
>>> x is not None
False
>>> x == None
True
>>> x != None
False

is None и is not None - правильные проверки на None.

Если х не None, то результаты проверок:

>>> x = 7
>>> x is None
False
>>> x is not None
True
>>> x == None
False
>>> x != None
True

Перепишем программу, которая находит максимум, через None:

def max2(x, y):                 # функция max2 - максимум из 2 чисел
    if x > y:
        return x
    else:
        return y

def mymax(a):                    # функция mymax - максимум в последовательности а
    res = None                   # сначала максимума нет (None)
    for x in a:
        if res is None:          # если максимума еще нет (первое число)
            res = x              # прочитанное число (первое!) - максимум
        res = max2(res, x)       # для первого числа res и x равны
        print('x=', x, 'res=', res)
    return res

a = map(int, input().split())    # читаем числа с клавиатуры
print('Максимум равен', mymax(a)) # вызываем функцию mymax

Проверяем, как работает программа:

# Input:
# -3 -7 -2 -10
# Output:
# x= -3 res= -3
# x= -7 res= -3
# x= -2 res= -2
# x= -10 res= -2
# Максимум равен -2

next(a) - взять следующий элемент последовательности

next(a) - функция языка питон, возвращает следующий элемент в последовательности.

Пусть последовательность - это числа 5, 12, -1. Переберем ее значения, используя функцию next.

>>> a = map(int, input().split())
5 12 -1
>>> x = next(a)
>>> x
5
>>> x = next(a)
>>> x
12
>>> x = next(a)
>>> x
-1
>>> x = next(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

Когда значения в последовательности закончились, функция next не смогла вернуть элемент, и кинула исключение StopIteration. Исключения мы изучим позже.

Перепишем программу поиска максимума через next:

Перепишем программу, которая находит максимум, через None:

def max2(x, y):                 # функция max2 - максимум из 2 чисел
    if x > y:
        return x
    else:
        return y

def mymax(a):                    # функция mymax - максимум в последовательности а
    res = next(a)                # пока максимум - первое число в последовательности
    for x in a:                  # начинаем перебирать со второго числа, первое уже прочитали!
        res = max2(res, x)       
        print('x=', x, 'res=', res)
    return res

a = map(int, input().split())    # читаем числа с клавиатуры
print('Максимум равен', mymax(a)) # вызываем функцию mymax

Проверяем, как работает программа:

# Input:
# -3 -7 -2 -10
# Output:
# x= -7 res= -3
# x= -2 res= -2
# x= -10 res= -2
# Максимум равен -2

Заметим, что перебирать в for .. in мы начали с числа -7. Число -2 мы взяли из последовательности раньше.

break - закончить цикл

Даны целые числа. Есть ли среди них число 5?

Если числа 5 нет, то нужно перебрать все числа, чтобы узнать это.

Если число 5 нашли, то дальше перебирать не нужно. Мы уже нашли число.

break - закончить цикл (перейти за конец цикла)

a = map(int, input().split())    # прочитали последователность в а
for x in a:                      # для каждого х в этих числах
    if x == 5:                   # если x равно 5
        print("Есть число 5")    # печатаем (один раз!)
        break                    # выходим из цикла (чтобы не печатать много раз)
    print(x)                     # печатаем каждый раз число х
else:                            # ТОЛЬКО если break не работал
    print("Нет числа 5")
                                 # конец цикла
                                 # сюда выйдет break

Проверим, как работет программа:

# Input:
# 3 7 -2 5 10 -33 5 5 5
# Output:
# 3
# 7
# -2
# Есть число 5

Заметим, мы закончили работать на первом числе 5 и следующие числа не печатали.

# Input:
# 3 7 -2 0
# Output:
# 3
# 7
# -2
# 0
# Нет числа 5

В for ... else и while ... else часть в else работает, если в цикле не работал break.

continue - продолжить цикл со следующего шага

continue - продолжить цикл со следующего шага.

Даны целые числа. Найдем в них все числа 5.

a = map(int, input().split())    # прочитали последователность в а
for x in a:                      # для каждого х в этих числах
    print(x)                     # печатаем каждый раз число х
    if x != 5:                   # если x ненужное число
        continue                 # пропускаем его и берем другое
    print("Есть число 5")        # печатаем

Проверим, как работает программа:

# Input:
# 3 5 7 -2 5 
# Output:
# 3
# 5
# Есть число 5
# 7
# -2
# 5
# Есть число 5

results matching ""

    No results matching ""