Python

Функции в Python. Преобразование нескольких однотипных функций в одну с помощью функции-ключа.

Зачастую в коде можно встретить множество однотипных функций, почти буквально одинаковых, за исключением 1-2 строк. В таких ситуациях, для устранения дублирования кода, имеет смысл попробовать свести все эти функции к одной общей функции. Пример ниже.

# Интересный пример, когда три однотипные функции можно превратить в одну


# ЗАДАЧА 1 ------------------------------------------------------------------------------
# Из этого списка нельзя получить максимальное число с помощью max(nums), ведь это строки
nums = ["12", "7", "30", "14", "3"]


# Напишем функцию для нахождения максимального числа в списке по критерию int
def max_by_int_value(items):
    biggest = items[0]
    for item in items[1:]:
        if int(item) > int(biggest):  # Эта строка отличает эту функцию от двух других
            biggest = item
    return biggest


print(max_by_int_value(nums))


# ЗАДАЧА 2 ------------------------------------------------------------------------------------
# Необходимо найти максимальное значение по модулю из списка разных, в т.ч. отрицательных чисел
# max(integers) здесь тоже не поможет
integers = [3, -2, 7, -1, -20]


# Напишем функцию для получения максимума по модулю
def max_by_abs(items):
    biggest = items[0]
    for item in items[1:]:
        if abs(item) > abs(biggest):  # Эта строка отличает эту функцию от двух других
            biggest = item
    return biggest


print(max_by_abs(integers))


# ЗАДАЧА 3 ----------------------------------------------------------------------------
# В качестве еще одного примера рассмотрим список объектов словаря:
student_joe = {'gpa': 3.7, 'major': 'physics', 'name': 'Joe Smith'}
student_jane = {'gpa': 3.8, 'major': 'chemistry', 'name': 'Jane Jones'}
student_zoe = {'gpa': 3.4, 'major': 'literature', 'name': 'Zoe Fox'}
students = [student_joe, student_jane, student_zoe]


# Необходимо найти запись о студенте, имеющем самый высокий средний балл (gpa)


def max_by_gpa(items):
    biggest = items[0]
    for item in items[1:]:
        if item["gpa"] > biggest["gpa"]:  # Эта строка отличает эту функцию от двух других
            biggest = item
    return biggest


print(max_by_gpa(students))
print()


# ПРОБУЕМ ИЗБАВИТЬСЯ ОТ ОДНОТИПНЫХ ФУНКЦИЙ ------------------------------
def max_by_key(items, key):
    """Здесь аргумент key может принимать значения вида int, abs и т.д.
    То есть key может передавать объект функции"""
    biggest = items[0]
    for item in items[1:]:
        if key(item) > key(biggest):
            biggest = item
    return biggest


print(max_by_key(nums, int))
print(max_by_key(integers, abs))


# А как же быть со студентами?
# Можно написать небольшую дополнительную функцию для получения элемента словаря И ПЕРЕДАТЬ ЕЕ В KEY
def get_gpa(who):
    return who["gpa"]  # Извлекает элемент словаря по ключу gpa


print(max_by_key(students, get_gpa))
print(max_by_key(students, lambda x: x["gpa"]))  # Можно обойтись без функции get_gpa.

Вставить формулу как
Блок
Строка
Дополнительные настройки
Цвет формулы
Цвет текста
#333333
Используйте LaTeX для набора формулы
Предпросмотр
\({}\)
Формула не набрана
Вставить