Функции. Продолжение

Распаковка и упаковка аргументов; параметры по умолчанию; функции как объекты первого класса; рекурсия

Распаковка и упаковка аргументов

  • Функции могут принимать неопределенное количество аргументов.

  • Для того, чтобы функция приняла и обработала все переданные позиционные аргументы, используется синтаксис *args:

def sum_all(*args):
    count = 0
    for n in args: # args это кортеж из переданных аргументов
        count += n
    return count

Практика: напишите функцию, которая перемножает все переданные ей аргументы

  • Это была упаковка аргументов. А так выглядит распаковка:

def greet(name, age):
    print(f"Привет, {name}! Тебе {age} лет.")

person_info = ('Анна', 25) # это тип данных кортеж, содержит 2 элемента
greet(*person_info)  # Распаковываем кортеж и передаем его как два аргумента
  • Вы увидели использование кортежей — это тип данных: неизменяемая последовательность. Поддерживает индексацию, срезы и большинство методов, используемых для других последовательностей.

Параметры по умолчанию

  • Параметры по умолчанию позволяют задать значения по умолчанию для аргументов функции. Если аргумент не передан при вызове функции, то будет использовано значение по умолчанию.

Пример:

def greet(name, age=30):
    print(f"Привет, {name}! Тебе {age} лет.")

greet("Максим")  # Если не передан второй аргумент, age будет равно 30

В этом примере age=30 устанавливает значение по умолчанию для аргумента age. Если age не передан при вызове, то будет использоваться 30.

Практика: определите функцию squaring (возведение в квадрат), которая имеет два параметра — число num и степень degree, которая по умолчанию равна 2.

Функции как объекты первого класса

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

def hello(name):
    print(f"Hello, {name}!")
    
greeting_func = hello
def apply(func, value):
    return func(value)

def double(x):
    return x * 2

result = apply(double, 5)
  • Рассмотрим другой пример с передачей функции в качестве аргумента другой функции:

def apply_function(numbers, function):
    results = []
    for number in numbers:
        result = function(number)
        results.append(result)
    return results
    
def square(number):
    return number ** 2
    
numbers = [1, 2, 3, 4, 5]
squared_numbers = apply_function(numbers, square)

Практика:

  • Создайте функцию filter_numbers(numbers, filter_func), которая принимает список чисел numbers и функцию filter_func. Функция filter_numbers должна вернуть новый список, содержащий только те числа из исходного списка, для которых filter_func возвращает True

  • Пример использования:

def is_even(x):
    return x % 2 == 0

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
filtered_numbers = filter_numbers(numbers, is_even)
print(filtered_numbers)
# [2, 4, 6, 8, 10]

Рекурсия

  • Рекурсия — определение, описание, изображение какого-либо объекта или процесса внутри самого этого объекта или процесса, то есть ситуация, когда объект является частью самого себя.

  • "Чтобы понять рекурсию, надо понять рекурсию"

  • Рекурсия в программировании — это вызов функции из неё самой

  • Принцип рекурсии — при каждом вызове подзадача должна становиться проще задачи. Важно предусмотреть крайний случай — до которого мы будем углубляться

def sum_range(n):
    if n == 1:
        return 1    
    return sum_range(n - 1) + n

# Что происходит? Функции при вызове внутри себя попадают в стек вызовов - по принципу стопки монет
# Как только функция достигнет крайнего случая - стек вызовов начнет выполнятся
# sum_range(5) - в стек
# sum_range(4) - в стек
# sum_range(3) - в стек
# sum_range(2) - в стек
# sum_range(1) - 1 - выполняется, т.к. мы предусмотрели крайний случай
# sum_range(2) - 3 - из стека и так далее
# sum_range(3) - 6
# sum_range(4) - 10
# sum_range(5) - 15
def matryoshka(n):
    if n == 1:
        print("Матрёшечка")
    else:
        print("Верх матрёшки n=", n)
        matryoshka(n - 1)
        print("Низ матрёшки n=", n)
  • Посмотрите на примеры функций. Попробуйте запустить код, проанализируйте результат

def print_numbers(n):
    if n > 0:
        print_numbers(n - 1)
        print(n)
def sum_list(lst):
    if not lst:
        return 0
    else:
        return lst[0] + sum_list(lst[1:])

Практика:

  • Напишите функцию, которая принимает число и возвращает его факториал

  • Напишите рекурсивную функцию нахождения числа Фибоначчи. Функция принимает порядковый номер числа Фибоначчи и возвращает его значение. Дополнительно: реализуйте задачу при помощи итеративной функции

Last updated