Функции
Пишем свои функции: проверку на простоту, сумму цифр, делители. Код становится короче, и его проще проверить. Заодно ускоряем перебор делителей в сотни раз.
- 1def и return
- 2Функция-проверка
- 3Быстрые делители
- 4Функция внутри условия
- 5Сломай код
- 6Где пригодится на ЕГЭ
def и return
Функцию ты уже много раз вызывал: print, len, int. Теперь научимся писать свои. Функция это кусок кода с именем: один раз написал, потом вызываешь сколько угодно.
def digit_sum(n): # имя функции и что она принимает s = 0 while n > 0: s += n % 10 n //= 10 return s # что функция отдаёт обратно print(digit_sum(2026)) print(digit_sum(999)) print(digit_sum(123) + digit_sum(456))
Как устроено:
def, имя, в скобках параметры, двоеточие. Тело функции с отступом;returnотдаёт результат туда, откуда функцию вызвали, и сразу заканчивает её работу;- сама по себе
defничего не выполняет. Код внутри сработает только при вызовеdigit_sum(...).
Параметров может быть несколько:
def to_base(n, k): # перевод числа n в систему с основанием k digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' s = '' while n > 0: s = digits[n % k] + s n //= k return s print(to_base(2026, 2)) print(to_base(2026, 16))
Это код из темы 5. Завернули его в функцию, и теперь переводить можно в любом месте одной строкой.
Функция-проверка
Самые полезные функции на ЕГЭ отвечают «да» или «нет»: возвращают True или False. Например, простое ли число.
def is_prime(n): if n < 2: return False # 0 и 1 не простые for d in range(2, n): if n % d == 0: return False # нашли делитель, дальше можно не искать return True # делителей не нашли print(is_prime(17), is_prime(21), is_prime(1))
Обрати внимание: return внутри цикла сразу выходит из функции. Если нашли хоть один делитель, ответ уже ясен. А return True стоит после цикла, без отступа от for: туда мы попадём, только если цикл прошёл до конца и ничего не нашёл.
Такую функцию удобно вставлять прямо в условие:
def is_prime(n): if n < 2: return False for d in range(2, n): if n % d == 0: return False return True print([n for n in range(1, 50) if is_prime(n)])
Быстрые делители
Перебор до n медленный. Для числа около миллиона это миллион шагов, а в №25 таких чисел тысячи. Ускорение строится на простом наблюдении: делители идут парами. Если 120 делится на 4, то делится и на 120 / 4 = 30. Один из пары всегда не больше корня из n.
Значит, хватит перебирать d, пока d * d <= n, и для каждого найденного добавлять сразу пару:
def divisors(n): res = [] d = 1 while d * d <= n: if n % d == 0: res.append(d) if d != n // d: # у квадрата пара совпадает, не добавляем дважды res.append(n // d) d += 1 return sorted(res) print(divisors(120)) print(divisors(36))
Для числа около миллиона это всего тысяча шагов вместо миллиона. Простоту так же проверяют до корня:
def is_prime(n): if n < 2: return False d = 2 while d * d <= n: if n % d == 0: return False d += 1 return True print(sum(1 for n in range(1, 101) if is_prime(n)))
У числа 36 делитель 6 в паре сам с собой: 36 / 6 = 6. Без проверки d != n // d он попадёт в список дважды, и количество делителей выйдет на 1 больше.
Сколько простых чисел от 1 до 10 000?
Сколько чисел от 1 000 000 до 1 001 000 включительно имеют ровно 4 делителя?
Функция внутри условия
В №15 дают длинную логическую формулу, где встречается «ДЕЛ(n, m)», то есть «n делится на m». Её удобно сделать функцией, тогда формула в коде выглядит почти как в условии:
def DEL(n, m): return n % m == 0 print(DEL(18, 6), DEL(18, 4))
Пример. Для какого наибольшего натурального A формула
ДЕЛ(x, A) ∨ (ДЕЛ(x, 6) → ¬ДЕЛ(x, 9))
истинна при любом натуральном x?
План: перебираем A, для каждого проверяем все x в большом диапазоне. Если хоть при одном x формула ложна, A не подходит.
def DEL(n, m): return n % m == 0 def ok(A): # истинна ли формула для всех x for x in range(1, 10000): if not (DEL(x, A) or (DEL(x, 6) <= (not DEL(x, 9)))): return False # нашли x, где формула ложна return True print([A for A in range(1, 200) if ok(A)])
Наибольшее подходящее A = 18. Функция ok устроена так же, как is_prime: ищем «плохой» случай и выходим, как только нашли. Следование → записано как <=, это было в теме 2.
Какое наибольшее A подходит в примере выше?
Среди чисел от 1 до 10 000, которые делятся на 7, найди число с наибольшей суммой цифр. В ответ запиши это число.
Сломай код
print вместо return
def square(n): print(n * n) x = square(5) + 1
Сначала вывелось 25, а потом ошибка unsupported operand type(s) for +: 'NoneType' and 'int'. Функция напечатала число, но ничего не вернула, а «ничего» в Python это None. Прибавить к нему 1 нельзя. Если результат нужен дальше, пиши return.
Тихая ошибка: return внутри цикла не на месте
def is_prime(n): for d in range(2, n): if n % d == 0: return False return True # отступ как у if, а должен быть как у for print(is_prime(9))
9 не простое, а функция сказала True. return True попал внутрь цикла и сработал на первом же шаге, после проверки только d = 2. Сдвинь его на уровень for.
NameError: переменная живёт внутри функции
def f(): k = 10 return k f() print(k)
name 'k' is not defined. Переменные, созданные внутри функции, снаружи не видны. Нужно сохранить результат: k = f().
Где пригодится на ЕГЭ
| Номер | Что из темы |
|---|---|
| №15 | функция DEL, проверка формулы для всех x через функцию |
| №25 | быстрые делители до корня, is_prime |
| №16 | функция, которая вызывает саму себя, это следующая тема |
| №5 | алгоритм над числом удобно оформить функцией R(n) |
Самое главное из темы, что нужно держать в голове к экзамену: функция divisors до корня. В №25 без неё код не уложится по времени, а с ней решение пишется за пять минут.
Код в блоках можно менять и запускать прямо в браузере.