Как пишется функция в питоне

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

Создание функции

Существуют некоторые правила для создания функций в Python.

  • Блок функции начинается с ключевого слова def, после которого следуют название функции и круглые скобки ( () ).
  • Любые аргументы, которые принимает функция должны находиться внутри этих скобок.
  • После скобок идет двоеточие ( : ) и с новой строки с отступом начинается тело функции.

Пример функции в Python:

def my_function(argument):
    print argument

 Вызов функции

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

Например:

my_function("abracadabra")

Вызывая функцию, мы можем передавать ей следующие типы аргументов:

  • Обязательные аргументы (Required arguments)
  • Аргументы-ключевые слова (Keyword argument)
  • Аргументы по умолчанию (Default argument)
  • Аргументы произвольной длины (Variable-length argumens)

Обязательные аргументы функции:

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

Например:

def bigger(a,b):
    if a > b:
        print a
    else:
       print b

# В описании функции указано, что она принимает 2 аргумента

# Корректное использование функции
bigger(5,6)

# Некорректное использование функции
bigger()
bigger(3)
bigger(12,7,3) 

Аргументы — ключевые слова

Аргументы — ключевые слова используются при вызове функции. Благодаря ключевым аргументам, вы можете задавать произвольный (то есть не такой каким он описа при создании функции) порядок аргументов.

Например:

def person(name, age):
    print name, "is", age, "years old"

# Хотя в описании функции первым аргументом идет имя, мы можем вызвать функцию вот так

person(age=23, name="John")

Аргументы, заданные по-умолчанию

Аргумент по умолчанию, это аргумент, значение для которого задано изначально, при создании функции.

Например:

def space(planet_name, center="Star"):
    print planet_name, "is orbiting a", center

# Можно вызвать функцию space так:
space("Mars")
# В результате получим: Mars is orbiting a Star

# Можно вызвать функцию space иначе:
space("Mars", "Black Hole")
# В результате получим: Mars is orbiting a Black Hole

Аргументы произвольной длины

Иногда возникает ситуация, когда вы заранее не знаете, какое количество аргументов будет необходимо принять функции. В этом случае следует использовать аргументы произвольной длины. Они задаются произвольным именем переменной, перед которой ставится звездочка (*).

Например:

def unknown(*args):
    for argument in args:
        print argument

unknown("hello","world") # напечатает оба слова, каждое с новой строки
unknown(1,2,3,4,5) # напечатает все числа, каждое с новой строки
unknown() # ничего не выведет

Ключевое слово return

Выражение return прекращает выполнение функции и возвращает указанное после выражения значение. Выражение return без аргументов это то же самое, что и выражение return None. Соответственно, теперь становится возможным, например, присваивать результат выполнения функции какой либо переменной.

Например:

def bigger(a,b):
    if a > b:
        return a # Если a больше чем b, то возвращаем a и прекращаем выполнение функции
    return b # Незачем использовать else. Если мы дошли до этой строки, то b, точно не меньше чем a

# присваиваем результат функции bigger переменной num
num = bigger(23,42)

Область видимости

Некоторые переменные скрипта могут быть недоступны некоторым областям программы. Все зависит от того, где вы объявили эти переменные.

В Python две базовых области видимости переменных:

  • Глобальные переменные
  • Локальные переменные

Переменные объявленные внутри тела функции имеют локальную область видимости, те что объявлены вне какой-либо функции имеют глобальную область видимости.

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

Например:

# глобальная переменная age
age = 44

def info():
    print age # Печатаем глобальную переменную age

def local_info():
    age = 22 # создаем локальную переменную age 
    print age

info() # напечатает 44
local_info() # напечатает 22

Важно помнить, что для того чтобы получить доступ к глобальной переменной, достаточно лишь указать ее имя. Однако, если перед нами стоит задача изменить глобальную переменную внутри функции — необходимо использовать ключевое слово global.

Например:

# глобальная переменная age
age = 13

# функция изменяющая глобальную переменную
def get_older():
    global age
    age += 1

print age # напечатает 13
get_older() # увеличиваем age на 1
print age # напечатает 14

Рекурсия

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

Напомним, что факториалом числа, например, 5 является произведение всех натуральных (целых) чисел от 1 до 5. То есть, 1 * 2 * 3 * 4 * 5

Рекурсивная функция вычисления факториала на языке Python будет выглядеть так:

def fact(num):
    if num == 0: 
        return 1 # По договоренности факториал нуля равен единице
    else:
        return num * fact(num - 1) # возвращаем результат произведения num и результата возвращенного функцией fact(num - 1)

Однако следует помнить, что использование рекурсии часто может быть неоправданным. Дело в том, что в момент вызова функции в оперативной памяти компьютера резервируется определенное количество памяти, соответственно чем больше функций одновременно мы запускаем — тем больше памяти потребуется, что может привести к переполнению стека (stack overflow) и программа завершится аварийно, не так как предполагалось. Учитывая это, там где это возможно, вместо рекурсии лучше применять циклы.

Рецепт создания функции в Python

Существует следующий алгоритм — рекомендация по созданию функции в Python. Например, мы создаем функцию вычисления площади прямоугольника.

  1. Начинать следует с примеров того, что делает функция, и подобрать подходящее название. В нашем случае это будет выглядеть так:
    # На данном этапе мы еще не указываем имена переменных
    def rectangle_area_finder( ):
        """
        >>> rectangle_area_finder(3, 5)
        15
        >>> rectangle_area_finder(17.2, 6)
        103.2
        """
  2. Указать типы данных, которые принимает функция и тип данных, который она возвращает
    # функция принимает два числа, а возвращает одно
    def rectangle_area_finder( ):
        """
        (num, num) -> num    
    
        >>> rectangle_area_finder(3, 5)
        15
        >>> rectangle_area_finder(17.2, 6)
        103.2
        """
  3. Подобрать подходящие названия для переменных
    # Поскольку это математическая функция нам вполне подойдут имена a и b
    def rectangle_area_finder(a, b):
        """
        (num, num) -> num
        
        >>> rectangle_area_finder(3, 5)
        15
        >>> rectangle_area_finder(17.2, 6)
        103.2
        """
  4. Написать краткое, но содержательное описание функции
    def rectangle_area_finder(a, b):
        """
        (num, num) -> num
    
        Returns an area of a rectangle with given sides a and b.    
    
        >>> rectangle_area_finder(3, 5)
        15
        >>> rectangle_area_finder(17.2, 6)
        103.2
        """
  5. Написать собственно тело функции
    def rectangle_area_finder(a, b):
        """
        (num, num) -> num
    
        Returns an area of a rectangle with given sides a and b.    
    
        >>> rectangle_area_finder(3, 5)
        15
        >>> rectangle_area_finder(17.2, 6)
        103.2
        """
        return a * b
  6. Функция готова! Осталось вызвать ее с указанными в примерах аргументами

python function call example, пример вызова функции в Python

Как видно, при вызове команды help() с именем нашей функции в качестве аргумента мы получаем написанную нами документацию.

Сопровождайте ваши функции качественной документацией и программисты, которые будут работать с вашим кодом после вас будут вам благодарны.

Содержание:развернуть

  • Синтаксис
  • Термины и определения
  • Важность функций
  • Абстракция

  • Возможность повторного использования

  • Модульность

  • Пространство имен

  • Объявление и вызов функций
  • Область видимости функций
  • Локальная (L)

  • Область объемлющих функций (E)

  • Глобальная (G)

  • Аргументы
  • Позиционные

  • Именованные

  • Необязательные параметры (параметры по умолчанию)

  • Аргументы переменной длины (args, kwargs)

  • Передача по значению и по ссылке

  • Словарь в качестве аргументов (упаковка)

  • Возвращаемые значения (return)
  • Что можно возвращать

  • Распаковка возвращаемых значений

  • Пустая функция

  • Чистые функции и побочные эффекты
  • Lambda функции
  • Docstring
  • Аннотация типов
  • Функции vs процедуры — в чем отличие?
  • Время выполнения функции
  • Вложенные функции и рекурсия

Функция — это фрагмент программного кода, который решает какую-либо задачу.

Его можно вызывать в любом месте основной программы. Функции помогают избегать дублирования кода при многократном его использовании. А также имеют ряд других преимуществ, описанных ниже.

Синтаксис

💁‍♀️ Простой пример: Вы торгуете мёдом, и после каждой продажи вам нужно печатать чек. В нём должно быть указано: название фирмы, дата продажи, список наименований проданных товаров, их количество, цены, общая сумма, а также сакраментальная фраза «Спасибо за покупку!».

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

print("ООО Медовый Гексагон")
print("Мёд липовый", end=" ")
print(1, end="шт ")
print(1250, end="р")
print("nCумма", 1250, end="р")
print("nСпасибо за покупку!")

А теперь представьте, что произойдёт, когда вы раскрутитесь, и покупатели станут приходить один за другим. В таком случае, чеки надо будет выдавать очень быстро. Но что делать, если вдруг нагрянет ваш любимый клиент и купит 10 сортов мёда в разных количествах? Далеко не все в очереди согласятся ждать, пока вы посчитаете общую сумму и внесёте её в чек.

Хорошо, что данный процесс можно легко оптимизировать с использованием функций.

def print_check(honey_positions):
sum = 0 # переменная для накопления общей суммы
print("ООО Медовый Гексагонn")
# в цикле будем выводить название, количество и цену
for honey in honey_positions:
name = honey[0]
amount = honey[1]
price = honey[2]
print(f"{name} ({amount} шт.) - {price} руб.")
sum += amount * price # здесь же будем считать ещё и общую сумму
print(f"nИтого: {sum} руб.")
print("Спасибо за покупку!")

Встаёт резонный вопрос: где же обещанное упрощение и куда подевались товары? Как раз для этого, мы и будем описывать состав покупки не напрямую в функции, а в отдельном списке кортежей. Каждый кортеж состоит из трёх элементов: название товара, количество и цена.

# (название, количество, цена за штуку)
honey_positions = [
("Мёд липовый", 3, 1250),
("Мёд цветочный", 7, 1000),
("Мёд гречишный", 6, 1300),
("Донниковый мёд", 1, 1750),
("Малиновый мёд", 10, 2000),
]

Теперь этот список передадим в функцию как аргумент, и самостоятельно считать больше не придётся.

print_check(honey_positions)

>
ООО Медовый Гексагон

Мёд липовый (3 шт.) - 1250 руб.
Мёд цветочный (7 шт.) - 1000 руб.
Мёд гречишный (6 шт.) - 1300 руб.
Донниковый мёд (1 шт.) - 1750 руб.
Малиновый мёд (10 шт.) - 2000 руб.

Итого: 40300 руб.
Спасибо за покупку!

Да, код стал более массивным. Однако теперь для печати чека вам не придётся самостоятельно вычислять итог. Достаточно лишь изменить количество и цену товаров в списке. Существенная экономия времени! Слава функциям!

Термины и определения

Ключевое слово def в начале функции сообщает интерпретатору о том, что следующий за ним код — есть её определение. Всё вместе — это объявление функции.

# объявим функцию my_function()
def my_function():
# тело функции

Аргументы часто путают с параметрами:

  • Параметр — это переменная, которой будет присваиваться входящее в функцию значение.
  • Аргумент — само это значение, которое передается в функцию при её вызове.

Параметры и аргументы функции

# a, b - параметры функции
def test(a, b):
# do something

# 120, 404 — аргументы
test(120, 404)

Ключевая особенность функций — возможность возвращать значение

Для этого используется слово return. Предположим, вы часто умножаете числа. Вы не осведомлены заранее, целые они или вещественные, но хотите, чтобы результат был целым всегда. Решим задачу с помощью функции:

# она будет принимать два множителя, а возвращать их округленное
# до целого числа произведение
def int_multiple(a, b):
product = a * b
# возвращаем значение
return int(product)

print(int_multiple(341, 2.7))

> 920

☝️ Главная фишка возвращаемых значений в том, что их можно использовать в дальнейшем коде: присваивать переменным, совершать с ними разные операции и передавать как аргументы в другие функции.

# найдём квадратный корень из возврата функции int_multiple
# во встроенную функцию sqrt() мы передали вызов int_multiple
print(math.sqrt(int_multiple(44, 44)))

> 44

Важность функций

Абстракция

Человек бежит, машина едет, корабль плывёт, а самолёт летит. Всё это — объекты реального мира, которые выполняют однотипные действия. В данном случае, они перемещаются во времени и пространстве. Мы можем абстрагироваться от их природы, и рассматривать эти объекты с точки зрения того, какое расстояние они преодолели, и сколько времени на это ушло.

Мы можем написать функцию, которая вычисляет скорость в каждом конкретном случае. Нам не важно, кто совершает движение: и для человека и для самолёта средняя скорость будет рассчитываться одинаково.

def calculate_speed(distance, time):
return distance / time

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

Возможность повторного использования

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

Например, при работе с массивами чисел, вам нужно часто их сортировать. Вместо того чтобы реализовать простой алгоритм сортировки (или использовать встроенную функцию), вам пришлось бы каждый раз перепечатывать тело этой или похожей функции:

# пузырьковая сортировка
def bubble_sort(nums):
for i in range(0, len(nums) - 1):
for j in range(len(nums) - 1):
if nums[j] > nums[j + 1]:
nums[j], nums[j + 1] = nums[j + 1], nums[j]
return nums

Всего 10 таких сортировок, и привет, лишние 50 строк кода.

Модульность

Разбитие больших и сложных процессов на простые составляющие — важная часть, как кодинга, так и реальной жизни. В повседневности мы занимаемся этим неосознанно. Когда убираемся в квартире, мы пылесосим, моем полы и окна, очищаем поверхности от пыли и наводим блеск на всё блестящее. Всё это — составляющие одного большого процесса под названием «уборка», но каждую из них также можно разбить на более простые подпроцессы.

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

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

Без применения модульности получится сплошная последовательность инструкций:

# Database operation program

# Код для чтения данных из базы
# ...
# ...

# Код для выполнения операций над данными
# ...
# ...

# Код для вывода результата
# ...
# ...

# Код для записи данных в базу
# ...
# ...

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

def read_from_db():
# Код для чтения данных из базы
# ...
# ...
# ...

def operate_with_data():
# Код для выполнения операций над данными
# ...
# ...
# ...

def print_result():
# Код для вывода результата
# ...
# ...
# ...

def write_to_db():
# Код для записи данных в базу
# ...
# ...
# ...

# код основной программы
# Database operation program
read_from_db()
operate_with_data()
print_result()
write_to_db()

Это и называется модульностью.

Пространство имен

Концепция пространства имён расширяет понятие модульности. Однако цель — не облегчить читаемость, а избежать конфликтов в названиях переменных.

💁‍♀️ Пример из жизни: в ВУЗе учатся два человека с совпадающими ФИО. Их нужно как-то различать. Если сделать пространствами имён группы этих студентов, то проблема будет решена. В рамках своей группы ФИО этих студентов будут уникальными.

Объявление и вызов функций

Объявим функцию:

def hello():
print('Adele is cute')

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

# код выполняется последовательно, поэтому сейчас интерпретатор
# не знает о существовании функции hello
hello()

def hello():
print('Adele is cute')

> NameError: name 'hello' is not defined

Поэтому стоит лишь поменять объявление и вызов местами, и всё заработает:

def hello():
print('Adele is cute')

hello()
> Adele is cute

Область видимости функций

Рассмотрим подробнее области видимости:

Локальная (L)

Локальная область видимости находится внутри def:

def L():
# переменная i_am_local является локальной внутри L()
i_am_local = 5

Область объемлющих функций (E)

Объявили функцию e(). Внутри неё объявили функцию inner_e(). Относительно inner_e() все переменные, объявленные в e() будут относиться к области объемлющих функций. Такие переменные являются нелокальными в inner_e(). Чтобы с ними взаимодействовать, нужно использовать ключевое слово nonlocal:

def e():
x = 5

def inner_e():
nonlocal x
x = x + 1
return x

return inner_e()

print(e())
> 6

Глобальная (G)

Глобальная область видимости лежит за пределами всех def.

# G
num = 42

def some_function(n):
res = n + num
return res

print(some_function(1))
> 43

Аргументы

Позиционные

Вспомним, аргумент — это конкретное значение, которое передаётся в функцию. Аргументом может быть любой объект. Он может передаваться, как в литеральной форме, так и в виде переменной.

Значения в позиционных аргументах подставляются согласно позиции имён аргументов:

nums = [42, 11, 121, 13, 7]
state = True

# в данном примере
# 1-я позиция "nums" -> parameter_1
# 2-я позиция "state" -> parameter_2
def test_params(parameter_1, parameter_2):
pass

# равнозначные варианты вызова функции
test_params(nums, state)
test_params([42, 11, 121, 13, 7], True)

Именованные

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

def print_trio(a, b, c):
print(a, b, c)

print_trio(c=4, b=5, a=6)

> 6 5 4

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

Необязательные параметры (параметры по умолчанию)

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

def not_necessary_arg(x='My', y='love'):
print(x, y)

# если не передавать в функцию никаких значений, она отработает со значениями по умолчанию
not_necessary_arg()
> My love

# переданные значения заменяют собой значения по умолчанию
not_necessary_arg(2, 1)
> 2 1

Аргументы переменной длины (args, kwargs)

Когда заранее неизвестно, сколько конкретно аргументов будет передано в функцию, мы пользуемся аргументами переменной длины. Звёздочка «*» перед именем параметра сообщает интерпретатору о том, что количество позиционных аргументов будет переменным:

def infinity(*args):
print(args)

infinity(42, 12, 'test', [6, 5])
> (42, 12, 'test', [6, 5])

Переменная args составляет кортеж из переданных в функцию аргументов.

Функции в питоне могут также принимать и переменное количество именованных аргументов. В этом случае перед названием параметра ставится «**«:

def named_infinity(**kwargs):
print(kwargs)

named_infinity(first='nothing', second='else', third='matters')
> {'first': 'nothing', 'second': 'else', 'third': 'matters'}

Здесь kwargs уже заключает аргументы не в кортеж, а в словарь.

Передача по значению и по ссылке

В Python аргументы могут быть переданы, как по ссылке, так и по значению. Всё зависит от типа объекта.

Передача аргументов в функцию по значению (num) и по ссылке (my_list)

Если объект неизменяемый, то он передаётся в функцию по значению. Неизменяемые объекты это:

  • Числовые типы (int, float, complex).
  • Строки (str).
  • Кортежи (tuple).

num = 42

def some_function(n):
# в "n" передается значение переменной num (42)
n = n + 10
print(n)

some_function(num)
print(num) # "num" по прежнему содержит 42

>
52
42

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

В Python изменяемые объекты это:

  • Списки (list).
  • Множества (set).
  • Словари (dict).

num = [42, 43, 44]

def some_function(n):
# в "n" передается ссылка на переменную "num".
# "n" и "num" ссылаются на один и тот же объект
n[0] = 0
print(n)

some_function(num)
print(num) # "num" изменился

>
[0, 43, 44]
[0, 43, 44]

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

💭 В функциональном программировании существует понятие «функциями с побочными эффектами» — когда функция в процессе своей работы изменяет значения глобальных переменных. По возможности, избегать таких функций.

Словарь в качестве аргументов (упаковка)

Передаваемые в функцию аргументы можно упаковать в словарь при помощи оператора «**»:

def big_dict(**arguments):
print(arguments)

big_dict(key='value')
> {'key': 'value'}

Возвращаемые значения (return)

Что можно возвращать

Функции в Python способны возвращать любой тип объекта.

Распаковка возвращаемых значений

В Питоне поддерживается возврат функциями сразу несколько значений. Достаточно перечислить их через запятую после инструкции return. Возвращаемым типом будет кортеж (tuple), который можно распаковать в переменные.

def calculate(num1, num2):
return num1 + num2, num1 - num2, num1 * num2

# для так называемой распаковки нескольких значений
# их следует присвоить равному количеству аргументов
res1, res2, res3 = calculate(7, 6)

print(res1, res2, res3)
> 13 1 42

print(type(calculate(7, 6)))
<class 'tuple'>

☝️ Обратите внимание, что количество возвращаемых значение в кортеже должно совпадать с количеством переменных при распаковке. Иначе произойдет ошибка:

def calculate(num1, num2):
return num1 + num2, num1 - num2

# для так называемой распаковки нескольких значений
# их следует присвоить равному количеству аргументов
res1, res2, res3 = calculate(7, 6)

print(res1, res2, res3)

>
ValueError: not enough values to unpack (expected 3, got 2)

Пустая функция

Иногда разработчики оставляют реализацию на потом, и чтобы объявленная функция не генерировала ошибки из-за отсутствия тела, в качестве заглушки используется ключевое слово pass:

def empty():
pass

Чистые функции и побочные эффекты

Немного функционального программирования. Есть такие функции, которые при вызове меняют файлы и таблицы баз данных, отправляют данные на сервер или модифицируют глобальные переменные. Всё это — побочные эффекты.

У чистых функций побочных эффектов нет. Такие функции не изменяют глобальные переменные в ходе выполнения, не рассылают и не выводят на печать никакие данные, не касаются объектов, и так далее.

Чистые функции производят вычисления по заданным аргументам и возвращают зависящий только от них самих результат.

Lambda функции

Кроме инструкции def в питоне можно создавать объекты функций в виде выражений. Так называемые анонимные функции создаются с помощью инструкции lambda. Чаще всего их применяют для получения встроенной функции или же для отложенного выполнения фрагмента программного кода.

lambda_test = lambda a, b: pow(a, b)

print(lambda_test(2, 4))
> 16

Docstring

Документировать код — особое искусство. Оно существует параллельно с разработкой и сопоставимо с ней по важности. Поэтому нередко документации в программе больше, чем самого кода.

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

Подробнее про docstring вы можете почитать тут:

Документирование кода в Python

Аннотация типов

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

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

def prod(a: int, b: int) -> int:
return a * b

В этой функции мы показали, что аргументы и результат должны быть целыми. Если передать float, то функция выполнится как обычно, однако IDE предупредит нас, что было получено неожиданное значение.

PyCharm предупреждает о передаче типа «str» вместо «int»

При этом интерпретатор считывает аннотации типов, но никак их не обрабатывает.

Функции vs процедуры — в чем отличие?

Для языка нет различий между функциями и процедурами. Но с точки зрения программиста — это разные сущности.

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

def proc(i, j):
pow(i, j)

proc(1, 200)

Она успешно отработает, но не вернёт нам результат. Поэтому добавляем ключевое слово return, и вот этот код обретает смысл:

def func(i, j):
return pow(i, j)

print(func(3, 2))
> 9

И наоборот, оформлять набор инструкций, выполняющий некую обработку, в виде функции также лишено смысла:

def print_low_word(word):
print(word.lower())
return 0

s = 'GOOD'
print_low_word(s)
> good

Возвращаемое значение не представляет собой никакой ценности, поэтому print_low_word(s) лучше оформить, как процедуру.

Время выполнения функции

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

from datetime import datetime
import time

start_time = datetime.now()
# здесь вызываем функцию
time.sleep(5)

print(datetime.now() - start_time)

Вложенные функции и рекурсия

Функции, которые объявляются и вызываются внутри других функций, называются вложенными.

def outerFunc():
def firstInner():
print('This is first inner function')

def secondInner():
print('This is second inner function')

firstInner()
secondInner()

outerFunc()
> This is first inner function
> This is second inner function

Рекурсия является частным случаем вложенной функции. Это функция, которая вызывает саму себя.

# посчитаем сумму чисел от 1 до num
def sum_from_one(num):
if num == 1:
return 1
return num + sum_from_one(num - 1)

print(sum_from_one(5))
> 15

😉

Назад в начало

Функция — это именованный блок кода, к которому можно обратиться из лю­бого места программы. У функции есть имя и список входных парамет­ров, а также воз­вращаемое значение.

Функция позволяет использо­вать в про­грамме один и тот же фрагмент кода нес­колько раз.

Oбъявление функции в Python выглядит так:

def function_name(argument1, argument2, …):

    # код функции

# def — DEclare Function — «объявить функцию»

# function_name — имя функции

# (argument1, argument2, …) — список аргументов, поступающих на вход функции при ее вызове

# тело функции — это весь код, который идет после двоеточия

# Объявление функции


def hello(name):

    print(‘Hello, ‘ + name)

# Вызовы функции


hello(‘Max’)

hello(‘Ivan’)

hello(‘Alex’)

hello(‘Kate’)

# Вывод


>> Hello, Max

>> Hello, Ivan

>> Hello, Alex

>> Hello, Kate

Оператор return возвращает значение из функции.

Представьте себе обычный калькулятор. Вы вводите первое число, операцию и второе число. Калькулятор возвращает нам результат операции над этими числами. Всё просто, не так ли? Функции точно так же умеют возвращать значение с помощью специального оператора return.

# Объявление функции


def sum2(a, b):

    return a + b

# Вызовы функции


s1 = sum2(10, 2)

s2 = sum2(108, 100)

s3 = sum2(3, 1)

print(f‘s1 = {s1})

print(f‘s2 = {s2})

print(f‘s3 = {s3})

>> s1 = 12

>> s2 = 208

>> s3 = 4

# Функция умножения двух чисел


def mult2(a, b):

    return a * b

# Вызовем нашу функцию


m1 = mult2(10, 2)

m2 = mult2(108, 100)

m3 = mult2(3, 1)

print(f‘m1 = {m1})

print(f‘m2 = {m2})

print(f‘m3 = {m3})

>> m1 = 20

>> m2 = 10800

>> m3 = 3

Для параметров функции можно указывать значения по умолчанию. Это дает возможность вызывать функцию с меньшим числом параметров.

# Аргумент name по умолчанию равен ‘world’


def hello(name=‘world’):

    print(‘Hello, ‘ + name)

hello()

hello(‘Ivan’)

>> Hello, world

>> Hello, Ivan

Примеры

1. Квадрат

# Написать функцию square(), вычисляющую квадрат числа.


def square(number):

    return number * number # Возвращаем результат работы функции обратно в программу


a = square(2)

print(a)

>> 4

2. Периметр

# Напишите функцию perimetr, вычисляющую периметр прямоугольника со сторонами a и b.


def perimetr(a, b):

    return 2 * (a + b)

p = perimetr(4, 3)

print(p)

>> 14

3. Четное число

# Напишите функцию isEven, возвращающую True, если число четное, и False, если — нечетное.


def isEven(x):

    return x % 2 == 0

print(isEven(10))

print(isEven(11))

>> True

>> False

4. Сумма списка

# Напишите функцию amountList, которая возвращает сумму всех элементов списка.


def amountList(lst):

    amount = 0

    for x in lst:

        amount += x

    return amount

print(amountList([1, 2, 3]))

mylist = [1, 2, 4, 8, 16]

s = amountList(mylist)

print(f‘Сумма списка {mylist} равна {s})

>> 6

>> Сумма списка [1, 2, 4, 8, 16] равна 31

5. Фибоначчи

# Напишите функцию fib, которая возвращает n-ное число Фибоначчи.

# Последовательность Фибоначчи выглядит так: 1 1 2 3 5 8 13 21 34


def fib(n):

    a, b = 0, 1

    if n == 0: return 0

    for i in range(1, n):

        a, b = b, a + b

    return b

print(fib(2))

print(fib(3))

print(fib(4))

print(fib(5))

print(fib(10))

>> 1

>> 2

>> 3

>> 5

>> 55

6. Факториал

# Напишите функцию fact, вычисляющую значение факториала числа N.

# Факториал числа — это произведение всех чисел от 1 до N.

# Например, факториал числа 5 равен 120 (5! = 120).


def fact(n):

    result = 1

    while n > 1:

        result *= n

        n -= 1

    return result

print(fact(2))

print(fact(3))

print(fact(4))

print(fact(5))

>> 2

>> 6

>> 24

>> 120

Решение задач

1. Площадь круга

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

# Не забудьте написать функцию circle…


print(circle(4))

print(circle(1))

# Вывод:

>> 50.24

>> 3.14

2. На три

Напишите функцию, которая возвращает True, если число делится на 3, и False, если — нет.

# Не забудьте написать функцию three…


print(three(4))

print(three(3))

# Вывод:

>> False

>> True

3. Максимум в списке

Напишите функцию, которая возвращает максимальный элемент из переданного в нее списка.

# Напишите функцию maxList…

mylist = [1, 3, 2]

print(maxList(mylist))

# Вывод:

>> 3

4. Сколько четных

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

# Напишите функцию evenCounter…

mylist = [1, 10, 2, 4, 6]

evens = evenCounter(mylist)

print(even)

# Вывод:

>> 4

5. Уникальные

Напишите функцию, которая возвращает список с уникальными (неповторяющихся) элементам.

# Напишите функцию unique…

mylist = [1, 1, 2, 1, 3, 2, 3]

print(unique(mylist))

# Вывод:

>> [1, 2, 3]

Разбираемся с основными составляющими функции в Python: аргументы, тело, возвращаемое значение. Изучаем структуру и синтаксис условного оператора if..elif..else. Учимся писать циклы for и while. Решаем задачи.

Logo Python Course Lesson 3

Урок 3
Функции, условные выражения и циклы

Разбираемся с основными составляющими функции в Python: аргументы, тело, возвращаемое значение. Изучаем структуру и синтаксис условного оператора if..elif..else. Учимся писать циклы for и while. Решаем задачи.

ТЕОРЕТИЧЕСКИЙ БЛОК

One

Функция

Функция — это блок организованного, многократно используемого кода, который используется для выполнения конкретного задания. Функции обеспечивают лучшую модульность приложения и значительно повышают уровень повторного использования кода.

Существуют некоторые правила для создания функций в Python.

  1. Блок функции начинается с ключевого слова def, после которого следуют название функции и круглые скобки ().
  2. Любые аргументы, которые принимает функция, должны находиться внутри этих скобок.
  3. После скобок идет двоеточие : и с новой строки с отступом начинается тело функции.

Python Функция Синтаксис

Функция в Python. Синтаксис.

Т. е. функция определяется следующим образом: def <имя_функции>(<аргументы функции>):.

Пример функции:

def calc(a, b):
    print(a)
    print(b)
    return a + b

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

Например:

Выражение return прекращает выполнение функции и возвращает указанное после выражения значение. Выражение return без аргументов — это то же самое, что и выражение return None. Соответственно, теперь становится возможным, например, присваивать результат выполнения функции какой либо переменной.

Например, создадим переменную sum и присвоим ей значение :

def calc(a, b):
    print(a)
    print(b)
    return a + b

sum = calc(21, 19)

Two

Аргументы функции

Вызывая функцию, мы можем передавать ей следующие типы аргументов:

  1. Обязательные аргументы (Required arguments)
  2. Аргументы-ключевые слова (Keyword arguments)
  3. Аргументы по-умолчанию (Default arguments)
  4. Аргументы произвольной длины (Variable-length argumens)

Рассмотрим каждый из типов подробнее.

1. Обязательные аргументы
Если при создании функции мы указали количество передаваемых ей аргументов и их порядок, то и вызывать ее мы должны с тем же количеством аргументов, заданных в нужном порядке.

Например:

# Определим функцию hour_to_sec
# Она переводит часы в секунды
def hour_to_sec(hour, min, sec):
     return hour * 60 * 60 + min * 60 + sec

# Вызовем функцию. Количество и порядок аргументов очень важны!
# Иначе результат вычислений будет неверным
>>> hour_to_sec(0, 5, 50)
350

2. Аргументы-ключевые слова
Аргументы-ключевые слова используются при вызове функции. Благодаря ключевым аргументам, вы можете задавать произвольный (то есть не такой, каким он описан при создании функции) порядок аргументов.

Например:

# Используем ту же самую функцию
def hour_to_sec(hour, min, sec):
     return hour * 60 * 60 + min * 60 + sec

# Хотя в определении первым параметром идут часы,
# мы можем передать секунды в качестве первого аргумента.
# В таком случае мы обязаны указать имя параметра
>>> hour_to_sec(sec=50, hour=0, min=5)
350

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

Например:

# Функция принимает два параметра: имя и возраст
# Параметр age имеет значение по-умолчанию
def person(name, age=25):
     print(name, 'is', age, 'years old')

# Передадим функции оба параметра и посмотрим результат
>>> person('Ivan', 19)
Ivan is 19 years old

# Теперь передадим функции только 1 параметр
# Параметр age примет свое значение по-умолчанию
>>> person('Ivan')
Ivan is 25 years old

4. Аргументы произвольной длины
Иногда возникает ситуация, когда вы заранее не знаете, какое количество аргументов будет необходимо принять функции. В этом случае следует использовать аргументы произвольной длины. Они задаются произвольным именем переменной, перед которой ставится звездочка (*).

Например:

# Определим функцию с произвольным количеством параметров
# Данная функция выводит переданные ей аргументы в консоль
def print_args(*args):
     print(args)

# Вызовем функцию без аргументов
>>> print_args()
()

# Вызовем функцию с 1 аргументом
>>> print_args('Строка')
('Строка')

# Вызовем функцию с 5ю аргументами
>>> print_args(1, 'Строка', 'Еще строка', 38, 4)
(1, 'Строка', 'Еще строка', 38, 4)

Задачи по теме


Функции, их типы, причины применения. Аргументы и параметры, разновидности. Примеры использования и задачи с решениями.


Three

Условные операторы

Условная инструкция if-elif-else (оператор ветвления) — основной инструмент выбора в Python. Говоря простым языком, она выбирает, какое действие следует выполнить, в зависимости от значения переменных в момент проверки условия. Существует несколько вариаций использования данной инструкции.

1. Условная конструкция if
Команда if в Python работает по той же схеме, что и в других языках программирования. Она содержит в себе логическое условие, и если это условие истинно (равно True) — выполнится блок кода, записанный внутри команды if. Если же логическое условие ложно (равно False), то блок кода записанный внутри команды if пропускается, а выполнение кода переходит на следующую после блока if строчку кода.

Python If Else Синтаксис

# Если число больше нуля, печатаем сообщение с данной информацией
# Если число НЕ больше нуля, то пропускаем содержимое блока if
# Переходим с следующей команде программы
if number > 0:
    print('Число больше нуля')
print('Идем дальше')

2. Конструкция if…else
В конструкцию if может быть добавлена команда else. Она содержит блок кода, который выполняется, если условие в команде if ложно.

Команда else является опциональной, в каждой if — конструкции может быть только одна команда else.

Например:

# Если выражение number > 0 истинно, то печатаем 'Число больше нуля'
# Если выражение number > 0 ложно, то печатаем 'Число меньше либо равно нулю'
if number > 0:
    print('Число больше нуля')
else
    print('Число меньше либо равно нулю')

3. Команда elif
Команда elif позволяет проверить истинность нескольких выражений и в зависимости от результата проверки выполнить нужный блок кода.

Как и команда else, команда elif является опциональной, однако, в отличие от команды else, у одной if-конструкции может существовать произвольное количество команд elif.

Например:

if number > 0:
    print('Число больше 0')
elif number == 0:
    print('Число равно 0')
else
    print('Число меньше 0')

А как же switch..case?
Условные конструкции, это типичная структура для реализации механизма принятия решений, и они существуют в подавляющем большинстве языков программирования. Обратите внимание, что базовый Python не поддерживает конструкцию switch/case, как, например, JavaScript, но ее можно реализовать при помощи if…elif…else конструкции.

Задачи по теме


Особенности и структура условных выражений в Python. Полные и неполные условные выражения, примеры задач с решениями.


Four

Проверка истинности в Python

Основные принципы проверки истинности выражений:

  1. Любое число, не равное 0, или непустой объект — истина.
  2. Числа, равные 0, пустые объекты и значение Noneложь.
  3. Операции сравнения применяются к структурам данных рекурсивно.
  4. Операции сравнения возвращают True или False


Логические операторы:

True False

Five

Циклы

Python Цикл For While Синтаксис

Циклы While и For в Python. Синтаксис.

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

  1. Цикл while
  2. Цикл for

.Поговорим о каждом из них более подробно.

1. Цикл while в Python
Инструкция while в Python повторяет указанный блок кода до тех пор, пока указанное в цикле условие будет оставаться истинным. While — один из самых универсальных циклов в Python, поэтому довольно медленный.

Цикл while записывается следующим образом:

while <условие>:
    <выражение>

При этом выражением может быть как одна так и несколько инструкций. Условием может быть любое истинное или не нулевое значение. Выражение будет повторяться, пока условие будет истинным.

Когда условие становится ложным интерпретатор переводит выполнение программы на строку, следующую за циклом. Рассмотрим следующий пример цикла:

apples = 5
# Запускаем цикл
while(apples > 0):
    # Работаем внутри цикла, печатаем сообщение
    print('We have', apples, 'apples')
    # Уменьшаем счетчик на 1
    apples -= 1
# Вышли из цикла
print('We have no apples any more!')

А вот как выглядит результат выполнения:

Терминал — интерактивный режим

>>> count_apples(5)
We have 5 apples
We have 4 apples
We have 3 apples
We have 2 apples
We have 1 apples
We have no apples any more!

Бесконечный цикл
Цикл while становится бесконечным в случае, когда условие цикла никогда не становится ложным. Примером задачи, для реализации которой необходим бесконечный цикл, может быть, например, создание программы «Часы», которая бесконечно будет обновлять и отображать время. Однако, часто бесконечный цикл является ошибкой начинающего программиста, который забыл добавить изменение условия цикла. Например:

num = 1
while num < 10 :

____print(‘We are still in cycle!’)

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

Задачи по теме


Задачи по циклам в Python: for, while. Синтаксис, особенности выхода из циклов, вложенные циклы.


2. Цикл for в Python

Цикл for уже чуточку сложнее, чуть менее универсальный, но выполняется гораздо быстрее цикла while. Этот цикл проходится по любому итерируемому объекту (например, строке или списку), и во время каждого прохода выполняет тело цикла. Синтаксис данного цикл выглядит следующим образом:

for <элемент> in <последовательность>:
    <выражение>

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

Например:

# Перебираем буквы в строке
word = 'Слово'
for letter in word:
    print(letter)

# Результат выполнения
С
л
о
в
о

# Перебираем элементы списка
shopping_list = ['milk', 'bread', 'cucumber', 'butter']
for element in shopping_list:
    print(element)

# Результат выполнения
milk
bread
cucumber
butter

# Перебираем элементы словаря
# По-умолчанию цикл проходится по ключам словаря
# Значение по ключу получаем самостоятельно seasons[s]
seasons = {1: 'Зима', 2: 'Весна', 3: 'Лето', 4: 'Осень'}
for s in seasons:
    print('Номер сезона:', s)
    print('Название:', seasons[s])

# Результат выполнения
Номер сезона: 1
Название: Зима
Номер сезона: 2
Название: Весна
Номер сезона: 3
Название: Лето
Номер сезона: 4
Название: Осень

Операторы continue и break
Оператор continue начинает следующий проход цикла, минуя оставшееся тело цикла ( for или while). Пример:

for letter in ‘Стол’:
____if letter == ‘т’:
________continue
____print(letter)

Результат выполнения:
С
о
л

Оператор break досрочно прерывает цикл. Пример:

for letter in ‘Стол’:
____if letter == ‘т’:
________break
____print(letter)

Результат выполнения:
С

Six

Функция range()

range() является универсальной функцией питона для создания списков( list), содержащих арифметическую прогрессию. Чаще всего она используется в циклах for.

Функция range() может принимать от одного до трех аргументов, при этом аргументами должны быть целые числа ( int). Так выглядит стандартный вызов функции range():

range(старт, стоп, шаг)

# Возвращает список целых чисел в форме
[старт, старт + шаг, старт + шаг*2 ..]

По умолчанию старт равняется нулю, шаг единице.
Примеры использований функции range() :

# Создаем последовательность с шагом 1
>>> for i in range(1, 5):
...     print(i)
1
2
3
4

# Создаем последовательность с шагом 3
>>> for i in range(0, 11, 3):
...     print(i)
0
3
6
9

Таким образом, функция range() позволяет нам генерировать ряд чисел в рамках заданного диапазона. В зависимости от того, как много аргументов вы передаете функции, вы можете решить, где этот ряд чисел начнется и закончится, а также насколько велика разница будет между двумя числами.

ПРАКТИЧЕСКИЙ БЛОК

One

Что такое IDE?

IDE (или интегрированная среда разработки) — это программа, предназначенная для разработки программного обеспечения. Как следует из названия, IDE объединяет несколько инструментов, специально предназначенных для разработки. Эти инструменты обычно включают:

  1. Редактор, предназначенный для работы с кодом (например, подсветка синтаксиса и автодополнение)
  2. Инструменты сборки, выполнения и отладки
  3. Определённую форму системы управления версиями.

Большинство IDE поддерживают множество языков программирования и имеют много функций, из-за чего могут быть большими, занимать много времени для загрузки и установки и требуют глубоких знаний для правильного использования.

С другой стороны, есть редакторы кода, которые представляют собой текстовый редактор с подсветкой синтаксиса и возможностями форматирования кода. Большинство хороших редакторов кода могут выполнять код и использовать отладчик, а лучшие даже могут взаимодействовать с системами управления версиями. По сравнению с IDE, хороший редактор кода, как правило, легковесней и быстрее, но зачастую ценой меньшей функциональности.

Итак, что нам нужно от среды разработки? Набор функций разных сред может отличаться, но есть набор базовых вещей, упрощающих программирование:

  1. Сохранение файлов.
  2. Запуск кода из среды.
  3. Поддержка отладки, т. е. возможности пошагового выполнения кода.
  4. Подсветка синтаксиса.
  5. Автоматическое форматирование кода.

Two

PyCharm

Одной из лучших полнофункциональных IDE, предназначенных именно для Python, является PyCharm. Существует как бесплатный open-source (Community), так и платный (Professional) варианты IDE. PyCharm доступен на Windows, Mac OS X и Linux.

PyCharm «из коробки» поддерживает разработку на Python напрямую — откройте новый файл и начинайте писать код. Вы можете запускать и отлаживать код прямо из PyCharm. Кроме того, в IDE есть поддержка проектов и системы управления версиями.

PyCharm Logo

Преимущества использования PyCharm: это среда разработки для Python с поддержкой всего и вся и хорошим коммьюнити. В ней «из коробки» можно редактировать, запускать и отлаживать Python-код.

Недостатки: PyCharm может медленно загружаться, а настройки по умолчанию, возможно, придётся подкорректировать для существующих проектов.

Three

Установка PyCharm

PyCharm Window

Как установить PyCharm? Легко! Выполняем несколько простых шагов:

  1. Скачиваем установочный файл с официального сайта. Обратите внимание, что качать надо бесплатную Community версию. Ссылка на страницу для скачивания: https://www.jetbrains.com/pycharm…
  2. Запустите установочный файл и следуйте инструкциям.

Демонстрацию установки PyCharm смотрите ниже в записи:

Хронометраж
00:25 Установка IDE PyCharm(Windows)
03:30 Настройка и запуск первой программы(Windows)
07:00 Установка IDE PyCharm(MacOS)
08:00 Настройка и запуск первой программы(MacOS)

Four

Разбираем задачи

Мы с вами изучили, как работать с условными выражениями и циклами в Python. Также выяснили, что для работы нам понадобится IDE PyCharm и получили инструкции по ее установке. Теперь пришло время воспользоваться нашими новыми знаниями и инструментами.

Приводим вам небольшой список задачек для тренировки:

Подробный разбор решения задач:

Хронометраж
00:40 Синтаксис функции
04:40 Отладка программы(Debug)
09:35 Точка входа в программу
12:00 Задача 1
18:40 Задача 2
27:10 Задача 3

Five

Домашнее задание

Предлагаем вам выполнить следующие действия:
1. Установить PyCharm(см. инструкцию по установке PyCharm в соответствующем пункте практической части урока)
2. Написать 2 небольших программы в качестве решения к следующим задачам:

Задача 1

Дан список lst = [11, 5, 8, 32, 15, 3, 20, 132, 21, 4, 555, 9, 20].
Необходимо вывести элементы, которые одновременно 1) меньше 30 и 2) делятся на 3 без остатка. Все остальные элементы списка необходимо просуммировать и вывести конечный результат.

Задача 2

Написать функцию month_to_season(), которая принимает 1 аргумент — номер месяца — и возвращает название сезона, к которому относится этот месяц.
Например, передаем 2, на выходе получаем ‘Зима’.

Делитесь возможными решениями задач в комментариях. Также предлагаем вам к рассмотрению и изучению наши варианты решений и соответствующие комментарии к каждому из заданий.

Как вам материал?

Читайте также

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

Что такое функция

Функция — это блок кода, который можно многократно вызывать на выполнение. Она является фундаментальной частью любого языка программирования.

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

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

Программист может написать собственную функцию или использовать готовые решения языка, если они есть, конечно. Например, лучше самому не написать функцию для определения максимального числа, а воспользоваться стандартной max().

Объявление

Объявляя функцию, нужно следовать определенным правилам:

  • Объявление происходит с помощью ключевого слова def, за ним идёт имя функции и круглые скобки ().
  • Аргументы, передаваемые в функцию, должны находится в круглых скобках. Там же можно определить их значения по умолчанию, указав их после знака равно.
  • Перед основным содержимым желательно включить строку документации (docstring), которая обычно описывает назначение  и основные принципы работы функции.
  • Тело функции начинается после знака двоеточия. Важно не забыть об отступах.
  • Чтобы выйти из функции в Python, используют оператор return [значение]. Если оператор опущен, будет возвращено значение None.

Функцию можно объявить где угодно: внутри модуля, класса или другой функции. Если она объявляет внутри класса, то называется методом класса и вызывается так: class_name.function().

Синтаксис объявления

Параметры (аргументы) нужно передавать в том порядке, в котором они определены в круглых скобках.

def Имя(аргументы):
    "Документация"
    Тело (инструкции)
    return [значение]

Пример кода

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

def print_sum(a = 2, b = 2):
    sum = a + b
    print(sum)
    return # вернёт None

Вызов

После определения функции её можно вызвать в любой точке скрипта, как в теле самого скрипта, так и в теле другой функции:

# определяем функцию
def print_sum(a = 2, b = 2):
    sum = a + b
    print(sum)
#вызываем её
print_sum(5, 1)

Значение функции можно сразу передать в переменную или в другую функцию:

def sum(a = 2, b = 2):
    sum = a + b
    return sum # вернёт сумму
c = sum(4, 3) # переменная c будет равна возвращаемому значению
print(sum(5, 5)) # можно передать значения в аргументы другой функции

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

Необязательные параметры

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

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

Вот пример:

def example(first, second=3, third=5):
    print(first)
    print(second)
    print(third)
example('my string', third=4)

Вывод будет следующим:

my string
3
4

Функция с переменным числом аргументов

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

Для того чтобы функция могла принять переменное количество аргументов, перед именем аргумента ставится символ » * «. Когда программист передаёт аргументы, они записываются в кортеж, имя которого соответствует имени аргумента:

def variable_len(*args):
    for x in args:
        print(x)
variable_len(1,2,3) # Выведет 1,2,3

Вместо одного символа звёздочки можно использовать два, тогда аргументы будут помещаться не в список, а в словарь:

def variable_len(**args):
    print(type(args))
    for x, value in args.items():
        print(x, value)
variable_len(apple = "яблоко", bread = "хлеб") 
# Выведет apple яблоко bread хлеб

Анонимные функции

Это особый вид функций, которые объявляются с помощью ключевого слова lambda вместо def:

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

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

Синтаксис

Синтаксис лямбда функции в Python 3 предусматривает использование только одного выражения: lambda arg1, arg2, … argn: выражение.
На практике они работают так:

x = lambda arg1, arg2: arg1 * arg2
print(x(5,5)) # Выведет 25
print(x(3,5)) # Выведет 15

Возврат значений

С помощью оператора return из функции можно вернуть одно или несколько значений. Возвращаемым объектом может быть: число, строка, None.

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

Вот пример когда возвращается список:

def x(n):
    a = [1,3]
    a = a * n
    return a
print(x(2)) # выведет [1,3,1,3]

А это пример того, как функция в Python 3 возвращает несколько значений. Так как переменные перечислены через запятую, то они образуют список. Эти значения можно присвоить сразу нескольким переменным, как это показано в следующем примере:

def example():
    language = "python"
    version = 3
    flag = True
    return language, version, flag
language, version, flag = example()
print(language, version, flag) # выведено будет python 3 True

Рекурсия

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

def f(num):
    if num == 0:
        return 1
    return f(num-1) * num
print(f(5)) # Выведет число 120

Рекурсию рекомендуется использовать только там, где это действительно необходимо. Интерпретатор Python автоматически выделяет память для выполняющейся функции, если вызовов самой себя будет слишком много, это приведёт к переполнению стека и аварийному завершению программы. Следующий код вызовет исключение «RecursionError», которая показывает, что превышен максимальный лимит рекурсии.

def x(num):
    a = num - 1
    print(a)
    x(a)
x(5)

Узнать максимальный лимит и его изменить можно с помощью getrecursionlimit() и setrecursionlimit(предел) из библиотеки sys.

Один из примеров применения рекурсии — это расчёт чисел Фибоначчи.

Пустая функция

Чтобы создать пустую функцию, нужно в её теле использовать оператор заглушки pass. Тогда она будет существовать и не выполнять никаких действий.

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

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

Вот пример:

def example():
    pass

Области видимости

Область видимости — важная составляющая любого языка программирования. С её помощью в одном модуле можно использовать одно и то же имя переменной несколько раз.

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

В Python существует две области видимости:

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

Важно понимать, из локальной области видимости можно обратить к переменным, находящимся в глобальной, но не наоборот.

Причём чтение глобальной переменной можно осуществить, просто обратившись к ней. А вот для записи надо отдельно указывать с помощью ключевого слова global, что мы работаем именно с глобальной переменной!

Вот пример:

val1 = "my global"
val2 = "another global"
def example():
    print(val1) # Выведет my global
    global val2
    val2 = "change another global"
example()
print(val2) # Выведет change another global

Подробнее про области видимости можно прочитать в отдельной статье на сайте.

Основные встроенные функции в Python

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

  • print() Выводит объекты на экран или в файл. Пример использования print("output string", end=""). Принимает аргументы:
    • object — то, что нужно вывести;
    • sep — разделитель, который ставиться между объектов, по умолчанию — пробел;
    • end — окончание после объекта, например управляющий символ «n»;
    • file — атрибут, позволяющий передать объект в файл (по умолчанию выводит на экран);
  • len() Возвращает количество элементов, содержащихся в кортеже, словаре или списке.
  • str() Преобразует переданный в качестве аргумента объект в строку.
  • int() Преобразует объект в целое число. Если передать в качестве аргумента строку, вызовется ошибка, целое число выведется без изменений, а у числа с плавающей точкой отбросится дробная часть.
  • range() Возвращает диапазон значений, в основном используется в условии цикла for.
  • bool() Приводит объект в логическому типу. Например, 0 — False, а 1 — True.
  • sum() Возвращает сумму переданных элементов.
  • min() и max() Возвращают минимальный и максимальный элемент из переданных.
  • type() Возвращает тип объекта, обычно используется при отладке кода.
  • dir() Возвращает список имён, доступных в локальной области видимости, или атрибуты объекта, переданного в качестве аргумента.
  • help() Выводит информацию о переданном объекте из встроенной справочной системы. Её целесообразно использовать только в интерактивном режиме Python интерпретатора.

Введение

Определение

Вот пример простой функции:

def compute_surface(radius):
    from math import pi
    return pi * radius * radius

Для определения функции нужно всего лишь написать ключевое слово def перед ее именем, а после — поставить двоеточие. Следом идет блок инструкций.

Последняя строка в блоке инструкций может начинаться с return, если нужно вернуть какое-то значение. Если инструкции return нет, тогда по умолчанию функция будет возвращать объект None. Как в этом примере:

i = 0
def increment():
    global i
    i += 1

Функция инкрементирует глобальную переменную i и возвращает None (по умолчанию).

Вызовы

Для вызова функции, которая возвращает переменную, нужно ввести:

surface = compute_surface(1.)

Для вызова функции, которая ничего не возвращает:

increment()

Еще

Функцию можно записать в одну строку, если блок инструкций представляет собой простое выражение:

def sum(a, b): return a + b

Функции могут быть вложенными:

def func1(a, b):

    def inner_func(x):
        return x*x*x

    return inner_func(a) + inner_func(b)

Функции — это объекты, поэтому их можно присваивать переменным.

Инструкция return

Возврат простого значения

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

Возврат нескольких значений

Пока что функция возвращала только одно значение или не возвращала ничего (объект None). А как насчет нескольких значений? Этого можно добиться с помощью массива. Технически, это все еще один объект. Например:

def stats(data):
    """данные должны быть списком"""
    _sum = sum(data) # обратите внимание на подчеркивание, чтобы избежать переименования встроенной функции sum
    mean = _sum / float(len(data)) # обратите внимание на использование функции float, чтобы избежать деления на целое число
    variance = sum([(x-mean)**2/len(data) for x in data])
    return mean,variance   # возвращаем x,y — кортеж!

m, v = stats([1, 2, 1])

Аргументы и параметры

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

Параметр — это имя в списке параметров в первой строке определения функции. Он получает свое значение при вызове. Аргумент — это реальное значение или ссылка на него, переданное функции при вызове. В этой функции:

def sum(x, y):
    return x + y

x и y — это параметры, а в этой:

sum(1, 2)

1 и 2 — аргументы.

При определении функции параметры со значениями по умолчанию нужно указывать до позиционных аргументов:

def compute_surface(radius, pi=3.14159):
    return pi * radius * radius

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

Выходит, что в следующем примере допущена ошибка:

def compute_surface(radius=1, pi):
    return pi * radius * radius

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

S = compute_surface(10, pi=3.14)

На самом деле, следующий вызов корректен (можно конкретно указывать имя позиционного аргумента), но этот способ не пользуется популярностью:

S = compute_surface(radius=10, pi=3.14)

А этот вызов некорректен:

S = compute_surface(pi=3.14, 10)

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

def compute_surface2(radius=1, pi=3.14159):
    return pi * radius * radius
S = compute_surface2(radius=1, pi=3.14)
S = compute_surface2(pi=3.14, radius=10.)
S = compute_surface2(radius=10.)

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

S = compute_surface2(10., 3.14)
S = compute_surface2(10.)

Если ключевые слова не используются, тогда нужно указывать все аргументы:

def f(a=1,b=2, c=3):
    return a + b + c

Второй аргумент можно пропустить:

f(1,,3)

Чтобы обойти эту проблему, можно использовать словарь:

params = {'a':10, 'b':20}
S = f(**params)

Значение по умолчанию оценивается и сохраняется только один раз при определении функции (не при вызове). Следовательно, если значение по умолчанию — это изменяемый объект, например, список или словарь, он будет меняться каждый раз при вызове функции. Чтобы избежать такого поведения, инициализацию нужно проводить внутри функции или использовать неизменяемый объект:

def inplace(x, mutable=[]):
   mutable.append(x)
   return mutable
res = inplace(1)
res = inplace(2)
print(inplace(3))
[1, 2, 3]
def inplace(x, lst=None):
   if lst is None: lst=[]
   lst.append()
   return lst

Еще один пример изменяемого объекта, значение которого поменялось при вызове:

def change_list(seq):
    seq[0] = 100
original = [0, 1, 2]
change_list(original)
original
[100, 1, 2]

Дабы не допустить изменения оригинальной последовательности, нужно передать копию изменяемого объекта:

original = [0, 1, 2]
change_list(original[:])
original
[0, 1, 2]

Указание произвольного количества аргументов

Позиционные аргументы

Иногда количество позиционных аргументов может быть переменным. Примерами таких функций могут быть max() и min(). Синтаксис для определения таких функций следующий:

def func(pos_params, *args):
    block statememt

При вызове функции нужно вводить команду следующим образом:

func(pos_params, arg1, arg2, ...)

Python обрабатывает позиционные аргументы следующим образом: подставляет обычные позиционные аргументы слева направо, а затем помещает остальные позиционные аргументы в кортеж (*args), который можно использовать в функции.

Вот так:

def add_mean(x, *data):
    return x + sum(data)/float(len(data))

add_mean(10,0,1,2,-1,0,-1,1,2)
10.5

Если лишние аргументы не указаны, значением по умолчанию будет пустой кортеж.

Произвольное количество аргументов-ключевых слов

Как и в случае с позиционными аргументами можно определять произвольное количество аргументов-ключевых слов следующим образом (в сочетании с произвольным числом необязательных аргументов из прошлого раздела):

def func(pos_params, *args, **kwargs):
    block statememt

При вызове функции нужно писать так:

func(pos_params, kw1=arg1, kw2=arg2, ...)

Python обрабатывает аргументы-ключевые слова следующим образом: подставляет обычные позиционные аргументы слева направо, а затем помещает другие позиционные аргументы в кортеж (*args), который можно использовать в функции (см. предыдущий раздел). В конце концов, он добавляет все лишние аргументы в словарь (**kwargs), который сможет использовать функция.

Есть функция:

def print_mean_sequences(**kwargs):
    def mean(data):
        return sum(data)/float(len(data))
    for k, v in kwargs.items():
        print k, mean(v)

print_mean_sequences(x=[1,2,3], y=[3,3,0])
y 2.0
x 2.0

Важно, что пользователь также может использовать словарь, но перед ним нужно ставить две звездочки (**):

print_mean_sequences(**{'x':[1,2,3], 'y':[3,3,0]})
y 2.0
x 2.0

Порядок вывода также не определен, потому что словарь не отсортирован.

Документирование функции

Определим функцию:

def sum(s,y): return x + y

Если изучить ее, обнаружатся два скрытых метода (которые начинаются с двух знаков нижнего подчеркивания), среди которых есть __doc__. Он нужен для настройки документации функции. Документация в Python называется docstring и может быть объединена с функцией следующим образом:

def sum(x, y):
    """Первая срока - заголовок

    Затем следует необязательная пустая строка и текст 
    документации.
    """
    return x+y

Команда docstring должна быть первой инструкцией после объявления функции. Ее потом можно будет извлекать или дополнять:

print(sum.__doc__)
sum.__doc__ += "some additional text"

Методы, функции и атрибуты, связанные с объектами функции

Если поискать доступные для функции атрибуты, то в списке окажутся следующие методы (в Python все является объектом — даже функция):

sum.func_closure   sum.func_defaults  sum.func_doc       sum.func_name
sum.func_code      sum.func_dict      sum.func_globals

И несколько скрытых методов, функций и атрибутов. Например, можно получить имя функции или модуля, в котором она определена:

>>> sum.__name__
"sum"
>>> sum.__module
"__main__"

Есть и другие. Вот те, которые не обсуждались:

sum.__call__          sum.__delattr__       sum.__getattribute__     sum.__setattr__
sum.__class__         sum.__dict__          sum.__globals__       sum.__new__           sum.__sizeof__
sum.__closure__       sum.__hash__          sum.__reduce__        sum.__str__
sum.__code__          sum.__format__        sum.__init__          sum.__reduce_ex__     sum.__subclasshook__
sum.__defaults__      sum.__get__           sum.__repr__

Рекурсивные функции

Рекурсия — это не особенность Python. Это общепринятая и часто используемая техника в Computer Science, когда функция вызывает сама себя. Самый известный пример — вычисление факториала n! = n * n — 1 * n -2 * … 2 *1. Зная, что 0! = 1, факториал можно записать следующим образом:

def factorial(n):
    if n != 0:
        return n * factorial(n-1)
    else:
        return 1

Другой распространенный пример — определение последовательности Фибоначчи:

f(0) = 1
f(1) = 1
f(n) = f(n-1) + f(n-2)

Рекурсивную функцию можно записать так:

def fibbonacci(n):
    if n >= 2:
        else:
    return 1

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

def factorial(n):
    assert n > 0
    if n != 0:
        return n * factorial(n-1)
    else:
        return 1

Важно!
Рекурсия позволяет писать простые и элегантные функции, но это не гарантирует эффективность и высокую скорость исполнения.

Если рекурсия содержит баги (например, длится бесконечно), функции может не хватить памяти. Задать максимальное значение рекурсий можно с помощью модуля sys.

Глобальная переменная

Вот уже знакомый пример с глобальной переменной:

i = 0
def increment():
    global i
    i += 1

Здесь функция увеличивает на 1 значение глобальной переменной i. Это способ изменять глобальную переменную, определенную вне функции. Без него функция не будет знать, что такое переменная i. Ключевое слово global можно вводить в любом месте, но переменную разрешается использовать только после ее объявления.

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

Присвоение функции переменной

С существующей функцией func синтаксис максимально простой:

variable = func

Переменным также можно присваивать встроенные функции. Таким образом позже есть возможность вызывать функцию другим именем. Такой подход называется непрямым вызовом функции.

Менять название переменной также разрешается:

def func(x): return x
a1 = func
a1(10)
10
a2 = a1
a2()
10

В этом примере a1, a2 и func имеют один и тот же id. Они ссылаются на один объект.

Практический пример — рефакторинг существующего кода. Например, есть функция sq, которая вычисляет квадрат значения:

def sq(x): return x*x

Позже ее можно переименовать, используя более осмысленное имя. Первый вариант — просто сменить имя. Проблема в том, что если в другом месте кода используется sq, то этот участок не будет работать. Лучше просто добавить следующее выражение:

square = sq

Последний пример. Предположим, встроенная функция была переназначена:

dir = 3

Теперь к ней нельзя получить доступ, а это может стать проблемой. Чтобы вернуть ее обратно, нужно просто удалить переменную:

del dir
dir()

Анонимная функция: лямбда

Лямбда-функция — это короткая однострочная функция, которой даже не нужно имя давать. Такие выражения содержат лишь одну инструкцию, поэтому, например, if, for и while использовать нельзя. Их также можно присваивать переменным:

product = lambda x,y: x*y

В отличие от функций, здесь не используется ключевое слово return. Результат работы и так возвращается.

С помощью type() можно проверить тип:

>>> type(product)
function

На практике эти функции редко используются. Это всего лишь элегантный способ записи, когда она содержит одну инструкцию.

power = lambda x=1, y=2: x**y
square = power
square(5.)
25
power = lambda x,y,pow=2: x**pow + y
[power(x,2, 3) for x in [0,1,2]]
[2, 3, 10]

Изменяемые аргументы по умолчанию

>>> def foo(x=[]):
...     x.append(1)
...     print x
...
>>> foo()
[1]
>>> foo()
[1, 1]
>>> foo()
[1, 1, 1]

Вместо этого нужно использовать значение «не указано» и заменить на изменяемый объект по умолчанию:

>>> def foo(x=None):
...     if x is None:
...         x = []
...     x.append(1)
...     print x
>>> foo()
[1]
>>> foo()
[1]

В предыдущих разделах мы уже часто сталкивались с встроенными функция ( int, float, print, type, len ) Каждая функция в Python предназначена для выполнения одной конкретной задачи. Использование функции упрощает написание и чтение кода. 

Содержание страницы:
1. Функция в Python
2. Передача аргументов функции
    2.1 Позиционные аргументы
    2.2. Именованные аргументы
    2.3. Значения по умолчанию
    2.4. Передача произвольного набора аргументов
    2.5. Позиционные аргументы с произвольным набором аргументов
    2.6. Произвольный набор именнованных аргументов
3. Возвращаемое значение в функции
    3.1. Возвращение простого значения
    3.2. Возвращение словаря
4. Использования функции в цикле while
5. Передача списка функции на Python
6. Использование лямбда-выражений вместо функций

1. Функция в Python

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

Напишем функцию, которая вычисляет квадрат своего аргумента и выводит на экран:

>>> def square(number):
…     «»»Вычисление квадрата числа»»»
…     print(number ** 2)

>>> square(5)
25
>>> square(124.45)
15487.802500000002

Определение функции начинается с ключевого слова def, за которым следует имя функцииsquare. Имя функции, как и имена переменных рекомендуется писать с букв нижнего регистра, а в именах, состоящих из нескольких слов, составляющие должны разделяться символами подчеркивания. Далее в круглых скобках записываются параметры (аргументы) функции, разделенные запятыми. Функция square имеет только один аргумент с именем number — значение, возводимое в квадрат. В случае отсутствия параметров у функции пустые круглые скобки обязательны. В конце строки за параметрами всегда ставится двоеточие ( : ).

После двоеточия новая строка должна идти с отступом (4 пробела). Все строки с отступом образуют тело или блок функции. В «Руководстве по стилю кода Python» указано, что первой строкой блока функции должна быть doc-строка, кратко поясняющая назначение функции: «»»Вычисление квадрата числа»»». Сам код в теле функции состоит всего из одной строки print(number ** 2).

Команда squre(5) вызывает функции square() и передает ей значение аргумента, для выполнения команды print. Функция возводит число в квадрат и выводит на экран. 

2. Передача аргументов функции в Python

2.1. Позиционные аргументы

Функция может иметь несколько параметров и при её вызове должно передаваться сразу несколько аргументов. Напишем функцию, которая выводит название автомобиля, модель и его пробег:

>>> def car(car_brend, car_model, mileage):
…     «»»Выводит информацию о автомобиле»»»
…     print(f»Продается {car_brend.title()} {car_model.upper()} с пробегом {mileage} км.»)

>>> car(‘bmw’, ‘x5’, 51345)
Продается Bmw X5 с пробегом 51345 км.

В данной функции видно, что должно передаваться три аргумента название автомобиля (car_brend), модель(car_model) и пробег (mileage). При вызове функции мы должны передать аргументы именно в том порядке, в каком они сохраняются в функции. Если нарушить порядок следования аргументов, то при вызове возможны неожиданные результаты или ошибки. 

2.2. Именованные аргументы

Если порядок передачи аргументов по каким то причинам не известен, то можно использовать именованные аргументы. Именованный аргумент представляет собой пару «имя-значение«. Имя и значения связываются с аргументом напрямую, так что при передаче аргумента путаница исключается. Вызовем туже самую функцию car() с помощью именованных аргументов:

>>> def car(car_brend, car_model, mileage):
…     «»»Выводит информацию о автомобиле»»»
…     print(f»Продается {car_brend.title()} {car_model.upper()} с пробегом {mileage} км.»)

>>> car(mileage = 45152, car_model = ‘x5′, car_brend=’bmw’)
Продается Bmw X5 с пробегом 45152 км.

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

2.3. Значения по умолчанию

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

>>> def car(car_model, mileage, car_brend=’bmv’):
…     «»»Выводит информацию о автомобиле»»»
…     print(f»Продается {car_brend.title()} {car_model.upper()} с пробегом {mileage} км.»)

>>> car(‘x7’, 12345)
Продается Bmv X7 с пробегом 12345 км.

>>> car(‘m5’ , 56148)
Продается Bmv M5 с пробегом 56148 км.

Для изменения значения по умолчанию, мы можем передать именованный аргумент для изменения значения car_brend=’audi’:

>>> car(‘q7’, 35600, car_brend=’audi’)
Продается Audi Q7 с пробегом 35600 км.

Так как аргумент для параметра  car_brend задан явно, Python игнорирует значение по умолчанию.

2.4. Передача произвольного набора аргументов

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

>>> def cars(*args):
…     «»»Вывод автомобилей»»»
…     print(args)

>>> cars(‘audi’, ‘bmv’, ‘ford’, ‘kia’)
(‘audi’, ‘bmv’, ‘ford’, ‘kia’)
>>> cars(‘porshe’)
(‘porshe’)

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

Для более удобной работы с данными, например изменения регистра символов можно воспользоваться циклом for:

>>> def cars(*args):
…     «»»Вывод автомобилей в продаже»»»
…     print(‘Автомобили в продаже:’)
…     for arg in args:
…             print(f»-{arg.title()}»)

>>> cars(‘audi’, ‘bmv’, ‘ford’, ‘kia’)
Автомобили в продаже:
-Audi
-Bmv
-Ford
-Kia

2.5. Позиционные аргументы с произвольным набором аргументов

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

>>> def car(car_brend, car_model, *colors):
…     «»»Выводит информацию о автомобиле»»»
…     print(f»Автомобиль {car_brend.title()} {car_model.upper()} можно заказать в цветах:»)
…     for color in colors:
…             print(f»-{color}»)

>>> car(‘bmw’, ‘x7’, ‘синий’, ‘зеленый’, ‘белый’, ‘черный’, ‘желтый’)
Автомобиль Bmw X7 можно заказать в цветах:
-синий
-зеленый
-белый
-черный
-желтый 

В результате данная функция получает два позиционных аргумента car_brend и car_model, а остальные сохраняются в кортеже colors

В большинстве программ часто используется имя обобщенного параметра *args для хранения произвольного набора позиционных аргументов.

2.6. Произвольный набор именованных аргументов

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

>>> def profile(first, last, **user_info):
…     «»»Возвращает словарь с данными о пользователе»»»
…     user_info[‘first_name’] = first
…     user_info[‘last_name’] = last
…     return user_info

>>> profile_1 = profile(‘tomas’, ‘edisson’, location=’usa’)
>>> print(profile_1)
{‘location’: ‘usa’, ‘first_name’: ‘tomas’, ‘last_name’: ‘edisson’}

Функция profile ожидает получить имя и фамилию пользователя, а также позволяет передать любое количество пар «имя — значение». Две звездочки в параметре **user_info заставляют Python создать пустой словарь с именем user_info и добавить в него все полученные пары «имя — значение». В теле функции сразу добавляются имя и фамилия, а остальные пары в зависимости от переданных параметров при вызове фукции.  В конце словарь возвращается с помощью команды return.

В программах часто используется имя обобщенного параметра **kwargs для хранения произвольного набора ключевых аргументов.

3. Возвращаемое значение в функции на Python

Вместо вывода результата работы напрямую, функция может обработать данные и вернуть значение c помощью команды return. Значение, возвращаемое функцией, называется возвращаемым значением.

3.1. Возвращение простого значения

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

>>> def form_name(last_name, first_name, middle_name):
…     «»»Возвращает отформатированное полное имя»»»
…     full_name = f»{last_name} {first_name} {middle_name}»
…     return full_name.title()

>>> poet = form_name(‘пушкин’, ‘александр’, ‘сергеевич’)
>>> print(poet)
Пушкин Александр Сергеевич

Функция form_name получает в параметрах имя, фамилию и отечество, далее объединяет эти имена и сохраняет их в переменной full_name. Завершив выполнение, функция возвращает управление в точку вызова с помощью команды return, то есть в строку кода, которая вызывала функцию. 

Предположим, что мы не знаем отчество человека, для передачи его фукции параметру middle_name. В связи с этим удобно заранее сделать в функции необязательный аргумент. Присвоим ( middle_name = «» ) пустое значение.

>>> def form_name(last_name, first_name, middle_name=»):
…     «»»Возвращает отформатированное полное имя»»»
…     full_name = f»{last_name} {first_name} {middle_name}»
…     return full_name.title()

>>> poet = form_name(‘пушкин’, ‘александр’)
>>> print(poet)
Пушкин Александр
>>> poet = form_name(‘пушкин’, ‘александр’, ‘сергеевич’)
>>> print(poet)
Пушкин Александр Сергеевич

С необязательным аргументом мы не получим ошибку (TypeError: form_name() missing 1 required positional argument: ‘middle_name’) в случае отсутствия на входе данных по аргументу.

3.2. Возвращение словаря

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

>>> def info_person(first_name, last_name):
…     «»»Возвращает словарь с данными о человеке»»»
…     person = {‘first’: first_name, ‘last’: last_name}
…     return person

>>> musician = info_person(‘Freddie’, ‘Mercury’)
>>> print(musician)
{‘first’: ‘Freddie’, ‘last’: ‘Mercury’}

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

4. Использования функции в цикле while

Функции могут вызываться в циклах while где угодно. Приведем пример цикла while, где у посетителя запрашивают имя и фамилию, а с помощью функции form_name возвращается отформатированное имя и фамилия с приветствием:

def form_name(first_name, last_name):
    «»»Возвращает отформатированное полное имя»»»
    full_name = f»{first_name} {last_name}»
    return full_name.title()

while True:
    print(«nВведите ‘x’ если хотите завершить программу»)
    first_name = input(«Введите ваше имя: «)
    if first_name == ‘x’:
        break
    last_name = input(«Введите вашу фамилию: «)
    if last_name == ‘x’:
        break
    formatted_name = form_name(first_name, last_name)
    print(f»nДобрый день {formatted_name}!»)

В данном примере в цикле whle запрашивается имя и фамилия и с помощью функции form_name возвращается отформатированное полное имя и записывается в переменную formatted_name. А затем уже с помощью функции print данные выводятся на экран. 

5. Передача списка функции на Python

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

>>> def square(numbers):
…     «»»Вычисление квадрата числа»»»
…     for number in numbers:
…             print(number ** 2)

>>> numbers = [1, 5, 6, 15, -7, 1.5]
>>> square(numbers)
1
25
36
225
49
2.25

В результате функции square мы передаем список numbers. Для возведения всех чисел в квадрат, вначале нам нужно перебрать данный список с помощью цикла for, а затем каждое число возвести в квадрат. 

6. Использование лямбда-выражений вместо функций

Для простых функций, например square, который просто вычисляют квадрат числа, можно использовать лямбда-выражения

>>> square = lambda x: x ** 2
>>> print(square(5))
25

В начале создается переменная square и в дальнейшем по имени переменной будет вызываться лямбда-выражение. Лямбда-выражение является анонимной функцией, то есть функцией, не имеющей имени. Лямбда-выражение начинается с ключевого слова lambda, за которым следует разделенный запятыми список параметров. В нашем примере параметр один x. Затем ставится двоеточие и само выражение x ** 2. В результате при вызове переменной square мы передаем параметр число 5, и оно возводится в квадрат. 

Лямбда-выражение может иметь и несколько параметров. Например, перемножать передаваемые числа. 

>>> mult = lambda x, y, z: x * y * z
>>> print(mult(2, 4, 6))
48

Таким образом любая простая функция в форме

def имя_функции(список_параметров):

return выражение

может быть выражена в более компактной форме посредством лямбда-выражения

lambda список_параметров: выражение

Далее: Классы в Python

Назад: Цикл while в Python

Функция – это мини-программа внутри основной программы. Код
такой подпрограммы отвечает за решение определенной задачи: например, в игре
Тетрис будут отдельные функции для подсчета очков, рисования игрового поля, движения
фигурки и так далее. Использование функций позволяет:

  • ограничить область видимости переменных функциями, которые их используют;
  • исключить дублирование кода;
  • разбить большую и сложную программу на небольшие мини-программы, которые можно вызывать в нужный момент;
  • выстроить простую и понятную структуру программы – такой код удобнее дебажить и поддерживать.

У функций есть несколько особенностей:

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

Python работает со встроенными и пользовательскими функциями. Встроенные функции – это уже знакомые нам print(), input(), map(), zip() и так далее. Пользовательские функции, в свою очередь, делятся на:

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

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

Объявление и вызов функций в Python

Для создания функции используют ключевое слово def. Вот пример простейшей функции, которая не получает и не возвращает никаких данных – просто выполняет одну команду по выводу строки с приветствием:

        def my_function():
  print('Привет от Python')

    

Для вызова такой функции достаточно написать ее название:

        my_function()
    

Результат вызова:

        Привет от Python
    

А это пример простейшей функции с параметром:

        def my_function(name):
    print(f'Привет, {name}')

    

При вызове функция получает аргумент:

        my_function('Вася')
    

Результат вызова:

        Привет, Вася
    

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

        def my_function(name, lastname):
    print(f'Добрый день, {name} {lastname}')

    

Если передать в функцию два аргумента – my_function('Егор', 'Куликов'), результат вызова будет таким:

        Добрый день, Егор Куликов
    

Но если число аргументов окажется меньше числа параметров – my_function('Алена'), возникнет ошибка:

            my_function('Алена')
TypeError: my_function() missing 1 required positional argument: 'lastname'

    

Порядок обработки позиционных аргументов

Python
обрабатывает позиционные аргументы слева направо:

        def my_function(name, last_name, occupation, age):
    print(f'Сотрудник #1 - {name} {last_name} {occupation} {age}')

info1, info2, info3, info4 = 'Алиса', 'Селезнева', 'скрам-мастер', 30
my_function(info1, info2, info3, info4)                  
my_function(info2, info3, info1, info4)                 
my_function(info4, info1, info2, info3)                 

    

Вывод:

        Сотрудник #1 - Алиса Селезнева скрам-мастер 30
Сотрудник #1 - Селезнева скрам-мастер Алиса 30
Сотрудник #1 - 30 Алиса Селезнева скрам-мастер

    

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

Функция может использовать аргументы по умолчанию – они
указываются после позиционных:

        def my_function(strt, build, ap, city='Москва'):
    print(f'Адрес: г.{city}, ул.{strt}, д.{build}, кв.{ap}')
my_function('Красная', '5', '3', 'Тула')
my_function('Красная', '5', '3')
Результат:
Адрес: г.Тула, ул.Красная, д.5, кв.3
Адрес: г.Москва, ул.Красная, д.5, кв.3

    

Именованные аргументы

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

        def sales_price(price, discount=5):
    return price - price * discount / 100

print(sales_price(5000))
print(sales_price(5000, discount=10))
print(sales_price(discount=15, price=5000))

    

Вывод:

        4750.0
4500.0
4250.0

    

Произвольное количество позиционных аргументов *args

До сих пор мы передавали в функцию определенное, заранее известное число позиционных аргументов. Если в функцию нужно передать произвольное количество
аргументов, используют *args:

        def my_function(*args):
    print(f'Минимальное число: {min(args)}, максимальное: {max(args)}')
my_function(1, 4, 5, 2, -5, 0, 12, 11)  

    

Результат вызова:

        Минимальное число: -5, максимальное: 12
    

При использовании *args функция получает кортеж аргументов, и к ним можно обращаться так же, как к элементам кортежа:

        def my_function(*args):
    print(f'Первое слово: {args[0]}, последнее слово: {args[-1]}')
my_function('яблоко', 'виноград', 'апельсин', 'арбуз', 'слива', 'груша')

    

Результат вызова:

        Первое слово: яблоко, последнее слово: груша
    

Название набора параметров, *args, используется по умолчанию. При
желании его можно изменить на любое другое название с * в начале:

        def my_function(*cities):
    print(f'Первый город: {cities[0]}, третий город: {cities[2]}')
my_function('Тюмень', 'Москва', 'Орел', 'Новгород', 'Ижевск', 'Ульяновск')  

    

Результат вызова:

        Первый город: Тюмень, третий город: Орел
    

Аргументы *args обрабатываются после позиционных, но до аргументов по умолчанию:

        def my_function(x, y, *args, kx=15, ky=15):
    print(x, y, args, kx, ky)
my_function(5, 6, 7, 8, 9, 0, 4)  

    

Вывод:

        5 6 (7, 8, 9, 0, 4) 15 15
    

Произвольное количество именованных аргументов **kwargs

Как уже было отмечено выше, именованные аргументы передаются в функцию в виде пар ключ=значение:

        def my_function(cat1, cat2, cat3):
    print(f'Младший кот: {cat1}, старший кот: {cat2}')
my_function(cat1='Том', cat2='Барсик', cat3='Полосатик')  

    

Результат вызова:

        Младший кот: Том, старший кот: Барсик
    

В приведенном выше примере количество именованных аргументов известно заранее. Если в функцию нужно передать произвольное количество пар
ключ=значение, используют параметр **kwargs. С **kwargs работают все методы словарей:

        def my_function(**kwargs):
    print(f'Самый легкий металл - {min(kwargs, key=kwargs.get)} {min(kwargs.values())}, самый тяжелый - {max(kwargs, key=kwargs.get)} {max(kwargs.values())}')
my_function(осмий=22.61, цинк=7.1, золото=19.3, ртуть=13.6, олово=7.3)

    

Результат вызова:

        Самый легкий металл - цинк 7.1, самый тяжелый - осмий 22.61
    

Как и в случае с *args, название по умолчанию **kwargs при желании можно заменить на любое другое с ** в начале:

        def my_function(**countries):
    print(f'Самая густонаселенная страна - {max(countries, key=countries.get)} {max(countries.values())} чел/км2, самая малонаселенная - {min(countries, key=countries.get)} {min(countries.values())} чел/км2')
my_function(Мальта=1432, Дания=128, Монако=18679, Индия=357, Монголия=2)  

    

Результат вызова:

        Самая густонаселенная страна - Монако 18679 чел/км2, самая малонаселенная - Монголия 2 чел/км2
    

Аргументы типа **kwargs обрабатываются после позиционных, *args и аргументов по умолчанию:

        def my_function(x, y, *args, kx=15, ky=15, **kwargs):
    print(x, y, args, kx, ky, kwargs)
my_function(7, 8, 0, 3, 4, 1, 8, 9, север=15, запад=25, восток=45, юг=10)

    

Вывод:

         7 8 (0, 3, 4, 1, 8, 9) 15 15 {'север': 15, 'запад': 25, 'восток': 45, 'юг': 10}
    

Передача аргументов в виде списка

Помимо кортежей и словарей, в функции можно передавать
списки:

        def my_function(stationery):
    for i, j in enumerate(stationery):
        print(f'Товар #{i + 1} - {j}')
        
stuff = ['карандаш', 'ручка', 'блокнот', 'альбом', 'тетрадь', 'ластик']   
my_function(stuff)

    

Результат вызова:

        Товар #1 - карандаш
Товар #2 - ручка
Товар #3 - блокнот
Товар #4 - альбом
Товар #5 - тетрадь
Товар #6 - ластик

    

Заглушка pass

Тело функции не может быть пустым – это приведет к сообщению
об ошибке:

        def my_function():
Вывод:
    def my_function():
                     ^
SyntaxError: unexpected EOF while parsing

    

Если по какой-то причине нужно оставить тело функции пустым, используют оператор pass, который выступает в роли заглушки:

        def my_function():
    pass

    

Функции с возвратом значений

Как уже было показано выше, функции могут получать и
обрабатывать любые типы данных – строки, числа, списки, кортежи, словари.
Результат обработки можно получить с помощью оператора return. Эта функция возвращает
произведение произвольного количества значений:

        def my_function(*args):
    prod = 1
    for i in args:
        prod *= i
    return prod    
print(my_function(5, 6, 3, 11))

    

Значения передаются в функцию при вызове – print(my_function(5, 6, 3, 11)). Результат при таком наборе цифр будет равен 990. Оператор return может возвращать любое количество значений, причем значения возвращаются в виде кортежа:

        def calculations(a, b):
    summa = a + b
    diff = a - b
    mul = a * b
    div = a / b
    return summa, diff, mul, div
num1, num2 = int(input()), int(input())
summa, diff, mul, div = calculations(num1, num2)
print(
    f'Сумма: {summa}n'
    f'Разница: {diff}n'
    f'Произведение: {mul}n'
    f'Результат деления: {div:.2f}n'
    )

    

Пример ввода:

        49
6

    

Вывод:

        Сумма: 55
Разница: 43
Произведение: 294
Результат деления: 8.17

    

Функция может содержать любое количество return. Эта функция возвращает различные оценки индекса массы тела:

        def bmi(h, w):
    bmi = w / (h / 100) ** 2
    if bmi <= 18.5:  
        return 'У вас дефицит веса' 
    elif bmi <= 24.9:  
        return 'Вес в норме' 
    elif bmi <= 29.9:  
        return 'Есть лишний вес'
    else:  
        return 'Срочно на диету!'
h = float(input('Введите рост в см: '))  
w = float(input('Введите вес в кг: '))
print(bmi(h, w))

    

Пример ввода:

        Введите рост в см: 172
Введите вес в кг: 61

    

Вывод:

        Вес в норме
    

Однако эту функцию можно переписать так, чтобы использовался только один оператор return:

        def bmi(h, w):
    bmi = w / (h / 100) ** 2
    if bmi <= 18.5:  
        res = 'У вас дефицит веса' 
    elif bmi <= 24.9:  
        res = 'Вес в норме' 
    elif bmi <= 29.9:  
        res = 'Есть лишний вес'
    else:  
        res = 'Срочно на диету!'
    return res    
h = float(input('Введите рост в см: '))  
w = float(input('Введите вес в кг: '))
print(bmi(h, w))

    

Практика

Задание 1

Напишите функцию для вывода треугольника. Функция принимает
два аргумента – size (размер сторон треугольника) и symb (символ, используемый для заполнения
треугольника).

Пример ввода:

        9
.

    

Вывод:

        .
..
...
....
.....
....
...
..
. 

    

Решение:

        def draw_triangle(size, symb):
    for i in range(1, size + 1):
        print(symb * min(i, size - i + 1))

size, symb = int(input()), input()
draw_triangle(size, symb)

    

Задание 2

Напишите функцию, которая принимает произвольное количество
целых чисел, и возвращает среднее арифметическое без использования встроенных
функции sum() и len().

Пример вызова:

        print(arith_mean(5, 5, 15, 25, 35))
    

Вывод:

        17.0
    

Решение:

        def arith_mean(*args):
    summa = 0
    kol = 0
    for i in args:
        summa += i
        kol += 1
    return summa / kol

    

Задание 3

Напишите функцию, которая:

  • принимает строку, состоящую из букв, цифр и специальных символов;
  • формирует три списка – 1) из цифр, 2) из букв, 3) из спецсимволов;
  • выводит списки на экран.

Пример ввода:

        23edwd893rjf934#$%Ye34F^(*))_+W$#Ddq2ddscew3r
    

Вывод:

        2 3 8 9 3 9 3 4 3 4 2 3
e d w d r j f Y e F W D d q d d s c e w r
# $ % ^ ( * ) ) _ + $ #

    

Решение:

        def sort_list(st):
    digits = [i for i in st if i.isdigit()]
    letters = [i for i in st if i.isalpha()]
    spec_char = [i for i in st if not i.isalnum()]
    print(*digits)
    print(*letters)
    print(*spec_char)
my_st = input()
sort_list(my_st)

    

Задание 4

Напишите функцию, которая начисляет новогодние премии
сотрудникам. Эта функция:

  • имеет два аргумента по умолчанию – salary=120000 и bonus=10 (оклад и премия);
  • получает два позиционных аргумента name и last_name – имя и фамилию сотрудника;
  • учитывает индивидуальные оклад и премию (см. примеры вызова);
  • выводит размер новогодней премии для сотрудника и зарплату с учетом премии.

Примеры вызова функции:

        ny_bonus('Алина', 'Тимофеева', salary=150000, bonus=25)
ny_bonus('Алексей', 'Ковалев', bonus=15)
ny_bonus('Игорь', 'Ефимов')
ny_bonus('Анастасия', 'Яковлева', salary=100000, bonus=20) 

    

Вывод:

        Новогодняя премия сотрудника Алина Тимофеева: 37500.00 руб.
Оклад: 150000.00 руб.
Всего к выдаче: 187500.00 руб.

Новогодняя премия сотрудника Алексей Ковалев: 18000.00 руб.
Оклад: 120000.00 руб.
Всего к выдаче: 138000.00 руб.

Новогодняя премия сотрудника Игорь Ефимов: 12000.00 руб.
Оклад: 120000.00 руб.
Всего к выдаче: 132000.00 руб.

Новогодняя премия сотрудника Анастасия Яковлева: 20000.00 руб.
Оклад: 100000.00 руб.
Всего к выдаче: 120000.00 руб.

    

Решение:

        def ny_bonus(name, last_name, salary=120000, bonus=10):
    print(f'Новогодняя премия сотрудника {name} {last_name}: {salary * bonus / 100:.2f} руб.n'
          f'Оклад: {salary:.2f} руб.n'
          f'Всего к выдаче: {salary + salary * bonus / 100:.2f} руб.n')

    

Задание 5

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

Пример ввода:

        5 7 8 9 34 28
    

Вывод:

        Есть
    

Решение:

        def perfect_number(n):
    sum = 0
    for i in range(1, n):
        if n % i == 0:
            sum += i
    return sum == n
numbers = list(map(int, input().split()))
flag = 'Нет'
for i in numbers:
    if perfect_number(i):
        flag = 'Есть'
        break
print(flag)

    

Задание 6

Напишите функцию, которая принимает два позиционных
аргумента – натуральные числа n и k,
и возвращает значение биномиального
коэффициента, не используя math.factorial().

Пример ввода:

        12
5
    

Вывод:

        792
    

Решение:

        def factorial(num):
    if num <= 1:
        return 1
    return num * factorial(num - 1)

def binomial_coeff(n, k):
    return int(factorial(n) / (factorial(k) * factorial(n - k)))

n, k = int(input()), int(input())
print(binomial_coeff(n, k))

    

Задание 7

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

Пример ввода:

        25
    

Вывод:

        двадцать пять
    

Решение:

        def spell_number(num):
    ed = ['один', 'два', 'три', 'четыре', 'пять', 'шесть', 'семь', 'восемь', 'девять', 'десять', 'одиннадцать', 'двенадцать', 'тринадцать', 'четырнадцать', 'пятнадцать', 'шестнадцать', 'семнадцать', 'восемнадцать', 'девятнадцать']
    des = ['двадцать', 'тридцать', 'сорок', 'пятьдесят', 'шестьдесят', 'семьдесят', 'восемьдесят', 'девяносто']
    if num < 20:
        return ed[num - 1]
    elif num >= 20:
        if str(num)[1] != '0':
            return des[int(str(num)[0]) - 2] + ' ' + ed[int(str(num)[1]) - 1]
    return des[int(str(num)[0]) - 2]     

n = int(input())
print(spell_number(n))

    

Задание 8

Напишите функцию, которая возвращает True, если введенная пользователем дата
является магической, и False в обратном случае. Магической считается дата, в которой
произведение дня и месяца равно двум последним цифрам года: 02.11.2022.

Пример ввода:

        03.06.2018
    

Вывод:

        True
    

Решение:

        def magic_date(date):
    return int(date[:2]) * int(date[3:5]) == int(date[-2:])

date = input()
print(magic_date(date))

    

Задание 9

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

Примеры вызова:

        print(make_query(category='books', genre='thriller', author='Stephen_King'))  
print(make_query(name='Егор', last_name='Тимохин', age=25, occupation='дизайнер'

    

Вывод:

        author=Stephen_King&category=books&genre=thriller
age=25&last_name=Тимохин&name=Егор&occupation=дизайнер

    

Решение:

        def make_query(**kwargs):
    return '&'.join([f'{k}={kwargs[k]}' for k in sorted(kwargs)]) 

    

Задание 10

Напишите функцию, которая принимает целое число n, и выводит на экран спиральную матрицу размера n x n, все элементы которой выровнены по левому краю.

Пример ввода:

        9
    

Вывод:

        1  2  3  4  5  6  7  8  9  
32 33 34 35 36 37 38 39 10 
31 56 57 58 59 60 61 40 11 
30 55 72 73 74 75 62 41 12 
29 54 71 80 81 76 63 42 13 
28 53 70 79 78 77 64 43 14 
27 52 69 68 67 66 65 44 15 
26 51 50 49 48 47 46 45 16 
25 24 23 22 21 20 19 18 17 
    

Решение:

        def print_matrix(n):
    matrix = [[0] * n for i in range(n)]
    vx, vy = [0, 1, 0, -1], [1, 0, -1, 0]
    x, y, z = 0, -1, 1
    for i in range(n + n - 1):
        for j in range((n + n - i) // 2):
            x += vx[i % 4]
            y += vy[i % 4]
            matrix[x][y] = z
            z += 1
    for i in range(len(matrix)):
        for j in range(len(matrix[i])):
            print(str(matrix[i][j]).ljust(3), end='')  
        print()    
print_matrix(int(input())) 
    

Подведем итоги

В этой статье мы научились создавать пользовательские
функции и передавать в них определенное число позиционных и именованных
аргументов, а также произвольное количество значений *args и **kwargs.

В следующей статье будем разбирать анонимные лямбда-функции.

***

Содержание самоучителя

  1. Особенности, сферы применения, установка, онлайн IDE
  2. Все, что нужно для изучения Python с нуля – книги, сайты, каналы и курсы
  3. Типы данных: преобразование и базовые операции
  4. Методы работы со строками
  5. Методы работы со списками и списковыми включениями
  6. Методы работы со словарями и генераторами словарей
  7. Методы работы с кортежами
  8. Методы работы со множествами
  9. Особенности цикла for
  10. Условный цикл while
  11. Функции с позиционными и именованными аргументами

В этой части мы изучим функции — составные инструкции, которые могут принимать данные ввода, выполнять указания и возвращать данные вывода. Функции позволяют определять и повторно использовать определенную функциональность в компактной форме.

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

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

f(x) = x * 2

Левая часть определяет функцию f, принимающую один параметр, x. А правая часть — это определение функции, которое использует переданный параметр x, чтобы произвести вычисление и вернуть результат. В этом случае значением функции является ее параметр, умноженный на два.

Как в Python функция записывается следующим образом: имя_функции (параметры_через_запятую). Чтобы вызвать функцию, после ее имени нужно указать круглые скобки и поместить внутрь параметры, отделив каждый из них запятой. Для создания функций в Python выберите ее имя, определите параметры, укажите, что функция должна делать и какое значение возвращать.

def имя_функции(параметры) :
    определениие _функции

Математическая функция f(x) = x * 2 в Python будет выглядеть вот так:

def f(x):
    return x * 2

Ключевое слово def сообщает Python, что вы определяете функцию. После def вы указываете имя функции; оно должно отвечать тем же правилам, что и имена переменных. Согласно конвенции, в имени функции нельзя использовать заглавные буквы, а слова должны быть разделены подчеркиванием вот_так.

Как только вы присвоили своей функции имя, укажите после него круглые скобки. Внутри скобок должен содержаться один или несколько параметров.

После скобок ставится двоеточие, а новая строка начинается с отступа в четыре пробела. Любой код с отступом в четыре пробела после двоеточия является телом функции. В этом случае тело нашей функции состоит только из одной строки:

return x * 2

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

Чтобы вызвать функцию в Python, мы используем синтаксис имя_функции (параметры, через, запятую).

Ниже описан вызов функции f из предыдущего примера с параметром 2.

f(2)

Консоль ничего не вывела. Можно сохранить вывод вашей функции в переменной и передать ее функции print.

# Продолжение
# предыдущего примера
def f(x):
    return x * 2
result = f(2)
print(result)  # 4

Вы можете сохранить результат, возвращаемый вашей функцией, в переменной и использовать это значение в программе позднее.

def f(x):
    return x + 1

z = f(4)
if z == 5:
    print("z равно 5")
else:
    print ("z не равно 5")

У функции может быть один параметр, несколько параметров или вообще их не быть. Чтобы определить функцию, не требующую параметров, оставьте круглые скобки пустыми.

def f():
    return 1 + 1

result = f()
print(result)  # 2

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

def f(x, y, z):
    return x + y + z

result = f(1, 2, 3)
print(result)  # 6

Наконец, функция не обязана содержать инструкцию return. Если функции нечего возвращать, она возвращает значение None.

def f():
    z = 1 + 1
result = f()
print (result)  # None

Обязательные и необязательные параметры

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

В Python есть и другой вид параметров — опциональные. Опциональные параметры определяются с помощью следующего синтаксиса: имя_функции(имя_параметра = значение_параметра). Как и обязательные, опциональные параметры нужно отделять запятыми. Ниже приведен пример функции, в коде которой используется опциональный параметр.

def f(x=2):
    return x**x

print (f())  # 4
print (f(4))  # 16

Сначала функция вызывается без передачи параметра. Так как параметр необязательный, x автоматически становится равен 2, и функция возвращает 4.

Затем та же функция вызывается с параметром 4. То есть x будет равен 4 и функция вернет 16. Вы можете определить функцию, которая принимает как обязательные, так и опциональные параметры, но обязательные нужно определять в первую очередь.

def add(x, y=10):
    return x + y
result = add(2)
print(result)

Функции существуют в большинстве современных языков программирования. В императивных языках (к которым относится и Python) функция — это набор инструкций, объединенных для выполнения одной задачи. Блоки кода, однажды оформленные в виде функций, можно использовать в коде многократно. Поэтому разработчики охотно применяют этот подход на практике, чтобы облегчить работу себе и своему приложению.

Помогаем

Редакция highload.today разобралась, как это работает, как создавать функции Python, на какие разновидности они делятся, как вызывать функции и передавать в них аргументы. Теперь мы готовы помочь разобраться в этом вам. И… да, примеры кода обязательно будут.

функции и их аргументы в Python

Содержание:
1. Что такое функция в Python
2. Именные функции (инструкция def)
3. Документирование функции
4. Аргументы функции
5. Инструкция return
6. Глобальные и локальные переменные
7. Рекурсивные функции
8. Анонимные функции (инструкция lambda)
9. Присвоение функции переменной
Заключение

1. Что такое функция в Python

В предыдущем абзаце уже шла речь о том, что функции Python делятся на разновидности. Мы рассмотрим две классификации:

  1. встроенные / не встроенные (пользовательские);
  2. Вибудовуйте якісний і привабливий бренд роботодавця всього за один місяць.

    РЕЄСТРУЙТЕСЯ!

    Contract agreement

  3. именные / без имени (анонимные).

Отличия между ними сводятся не только к синтаксису и способу использования. Не менее важно, что работают они тоже по-разному (далее мы в этом убедимся).

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

Встроенная функция Python Краткое описание
len() вычисляет длину (количество элементов) последовательности (например, списка)
next() возвращает следующий по порядку элемент последовательности (например, списка)
reversed() меняет порядок элементов последовательности на обратный

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

Пользовательские функции разработчики приложений на Python должны создавать самостоятельно. Для этого в языке существуют специальные конструкции, которыми нужно просто научиться пользоваться. И чем лучше вы этому научитесь, тем лучше будет выглядеть ваш код. И более того, его будет проще поддерживать и дорабатывать. Пользовательские функции помогают:

  • разделить объемный код на понятные, осмысленные части;
  • вынести повторяющийся код в один блок;
  • оптимизировать скорость работы приложения.

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

2. Именные функции (инструкция def)

Из названия термина ясно, что синтаксис такой функции обязательно должен включать ее имя:

def function_name(parameters):
    """здесь можно описать, что делает функция"""
    statement(s)
return result

Первая строка — заголовок функции. Далее следуют опциональная строковая переменная (в тройных кавычках) и тело функции (обозначено как statement(s)).

У синтаксиса функции есть ряд особенностей:

  1. Заголовок функции должен начинаться с ключевого слова def.
  2. Функция должна иметь уникальное имя (уникальное внутри определенных областей видимости — о них расскажем позже).
  3. В функцию для обработки можно передать произвольное количество параметров. Но это необязательно.
  4. Заголовок функции обязательно должен заканчиваться двоеточием.
  5. Между тройными кавычками можно написать, что делает функция (об этом поговорим в другом разделе).
  6. Тело функции — это тот самый набор инструкций, объединенных для общей задачи. Туда и надо писать код, отвечающий за всю логику работы функции.
  7. Описательную переменную с тройными кавычками и все инструкции внутри тела нужно располагать со смещением в 4 пробела от слова def — по горизонтали вправо.
  8. По итогам работы функции с помощью инструкции return можно вернуть результат — в виде числа или списка например. Но это необязательно.

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

Пример:

def greet(name):
    """  Функция выводит приветственное сообщение для имени name """
    print("Hello, " + name + ". Good morning!")

Напомним также общие правила именования переменных, которые полностью распространяются и на имена функций:

  1. Имя может состоять из чисел, латинских символов и символа нижнего подчеркивания и не должно включать что-либо другое.
  2. Имя функции не должно включать пробелы.
  3. В начале имени нельзя ставить цифру.
  4. X и x — это два разных идентификатора (регистр имеет значение).
  5. Имена функций рекомендуют начинать со строчной буквы.
  6. В качестве имени пользовательской функции запрещено использовать ключевые слова языка Python и имена его встроенных функций.

Вызов функции

Функцию можно вызвать из консоли Python, из скрипта или из другой функции. Чтобы сделать это для именной функции мы должны написать ее имя, а в скобках при необходимости передать ей параметры, либо оставить скобки пустыми.

>>> say_goodbye('Paul')
Goodbye, Paul.

вызов функции из консоли Python

def say_goodbye(name):
        print("Goodbye, " + name)

say_goodbye('Paul')

вызов функции say_goodbye из скрипта Python и вызов функции print из функции say_goodbye

ВАЖНО: язык Python не позволяет вызывать функцию до того, как она была создана. Потому что анализатор Python в данном случае сканирует код сверху вниз и не может найти объявление функции, которая была вызвана.

# вызов функции
say_goodbye('Paul')

# реализация функции
def say_goodbye(name):
        print("Goodbye, " + name)

# Ошибка: в точке say_goodbye('Paul') функция 'say_goodbye' не определена, не существует

вызов функции до ее объявления

Без вызова именная функция никогда не запустится. То есть, мы обязательно должны вызвать именную функцию, чтобы заставить работать код внутри нее, включая инструкцию return, о которой расскажем в специальном разделе.

функции и их аргументы в Python

Источник: www.programiz.com

3. Документирование функции

После заголовка функции идет опциональная строка, в которой можно написать любой текст. Но в данном случае она нужна для описания, документирования работы функции. Ее еще называют иностранным словосочетанием docstring. Вряд ли вы помните, что делает и как работает каждая функция, которую вы написали. Если даже вы это помните, то остальные разработчики, которые будут сопровождать или как-то еще использовать ваш код, не в курсе.

Поэтому такое документирование позволяет в итоге сэкономить время. А те минуты, которые вы потратите на него, окупятся с избытком.

Вспомним функцию из предыдущего примера и добавим в нее docstring:

def greet(name):
    """  Функция выводит приветственное сообщение для имени name """
    print("Hello, " + name + ". Good morning!")

объявление функции с документированием

Все, теперь, встретившись с таким кодом, другие разработчики сразу поймут, что к чему. Понятно, что тут очень простой пример, но представьте, что это большой и запутанный код.

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

>>> print(greet.__doc__)

    Функция выводит приветственное сообщение для имени name

вывод значения атрибута __doc__ для функции greet

4. Аргументы функции

def function_name(parameters):

Вновь вернемся к заголовку функции и разберемся, какими могут быть эти самые параметры, они же — аргументы. Сколько их может быть? В предельном случае их может не быть вовсе. Тогда получаем такой заголовок:

def function_name():

и вот такой вызов функции:

function_name();

Рассмотрим теперь более распространенный случай, когда аргументов несколько.

def say_goodbye(name, msg):
    print("Goodbye", name + ', ' + msg)

say_goodbye("Monica", "Sweet dreams!")

Функция say_goodbye принимает два аргумента — переменные name и msg. Вызывая функцию, мы передаем в нее значения, которые соответствуют аргументам. То есть эти значения (“Monica” и “Sweet dreams!“) подставляются вместо переменных name и msg соответственно.

Результат работы программы:

Goodbye Monica, Sweet dreams!

Отлично. Два аргумента — два переданных значения. Все работает.

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

>>> say_goodbye("Monica")    
TypeError: say_goodbye() missing 1 required positional argument: 'msg'

>>> say_goodbye()    
TypeError: say_goodbye() missing 2 required positional arguments: 'name' and 'msg'

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

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

Значения аргументов по умолчанию

Python позволяет задавать значения аргументов по умолчанию.

def say_goodbye(name, msg="Sweet dreams!"):

    print("Goodbye", name + ', ' + msg)

Конструкция msg="Sweet dreams!" в первой строке означает, что при вызове функции значение аргумента msg можно не задавать. Достаточно задать только значение аргумента name, а значение msg подставится само.

say_goodbye("Monica")

И тогда программа будет работать без ошибок:

Goodbye Monica, Sweet dreams!

При этом вариант вызова с полным количеством аргументов также будет работать

say_goodbye("Bruce", "See you!")

и программа выдаст

Goodbye Bruce, See you!

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

Однако, в силу особенностей языка Python, мы не можем переписать код так:

def say_goodbye(msg = "Sweet dreams!", name):

Потому что получим ошибку.

SyntaxError: non-default argument follows default argument

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

Порядок передачи аргументов

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

Вот такой код

say_goodbye("See you!", "Bruce")

приведет к следующему результату:

Goodbye See you!, Bruce

Потому что в объявлении функции аргументы расположены не в том порядке:

def say_goodbye(name, msg):

В Python такие аргументы называются позиционными. Но существуют и аргументы другого типа — именованные или ключевые (калька с английского keyword arguments). Если точнее, то существует другой способ передачи значений аргументов при вызове функции.

# 2 ключевые аргументы
say_goodbye(name = "Bruce", msg = "See you!")

# 2 ключевые аргументы в другом порядке
say_goodbye(msg = "See you!",name = "Bruce") 

Такая конструкция позволяет игнорировать порядок передачи аргументов при вызове функции. Хотя можно использовать и смешанный вариант:

# позиционный и ключевой аргумент
say_goodbye("Bruce", msg = "See you!")      

Функции с неизвестным количеством аргументов

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

def say_goodbye(*names):
    """Функция выведет приветствие для каждого
имени из полученного names"""
                
    for name in names:
        print("Goodbye", name)

В этом случае перед именем списка пишется знак *. Тут names — это список имен неизвестной длины. Функция обрабатывает его, как обычный список.

Вызывая эту функцию, мы можем в качестве аргументов передавать произвольное количество значений. Они преобразуются в список и полученный список автоматически подставляется вместо переменной names.

say_goodbye("Monica", "Luke", "Steve", "John")

Результат работы программы:

Goodbye Monica
Goodbye Luke
Goodbye Steve
Goodbye John

5. Инструкция return

Несмотря на то, что эта инструкция опциональная, она помогает в двух случаях:

  • Когда нужно вернуть результат работы функции в виде значения, которое может использовано вне функции — например, записано во внешнюю переменную.
def sum(a,b):
return a+b
  • Когда нужно прервать работу функции и вернуться к той точке программы, из которой была вызвана эта функция.
def division(a,d):
    if d == 0:    # если делитель равен нулю
    return "Нельзя делить на ноль"  # мы прерываем работу функции

    return a / d

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

print(sum(2, 4))
print(sum(2, -4))

Получим

6
-2

print(division(4, 2))
print(division(4, 0))

Получим

2.0
Нельзя делить на ноль

Если в коде функции нет инструкции return, она не возвращает ничего. Запустив в консоли функцию из предыдущего раздела, в третьей строке мы получим None.

>>> print(say_goodbye("May"))
Goodbye, May. 
None

6. Глобальные и локальные переменные

В этой статье мы еще не встречали функции, в которых помимо аргументов использованы переменные. Например:

def multiplicator(x):
    k = 2
    return k * x

Что это за переменная k?

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

В приведенном выше примере переменная k видна только внутри функции. В этом случае говорят, что переменная является локальной.

Время жизни переменной — это временной промежуток, в течение которого переменная хранится в памяти (и доступна хотя бы для чтения).

Локальные переменные обычно живут до тех пор, пока функция не завершит свою работу после очередного вызова. Во время каждого вызова функции все ее локальные переменные сбрасываются и инициализируются заново. Значения (если они были изменены) локальных переменных из предыдущих вызовов функция не хранит.

Хорошо, тогда что будет, если создать переменную с тем же именем, но за пределами функции?

def multiplicator(x):
    k = 2
print("Значение локальной переменной k:", k)
    return k*x

k = 20
multiplicator(4)
print("Значение внешней переменной k:", k)

А вот что:

Значение локальной переменной k: 2
Значение внешней переменной k: 20

В этом примере внешняя переменная k никак не влияет на результат работы функции. Дело в том, что сначала функция ищет переменную с подходящим именем внутри своей локальной области видимости — где как раз находится локальная переменная k.

функции и их аргументы в Python

Если мы удалим эту переменную из реализации функции, то она будет искать k уже во внешних по отношению к ней блоках кода (пошагово двигаясь изнутри наружу). В данном случае она найдет внешнюю переменную k, равную 20 и использует ее значение для своих вычислений.

Но если нам нужно не просто использовать, а еще и модифицировать это значение, необходимо внести изменения в код:

def multiplicator(x):
    global k
k = 2
print("Значение локальной переменной k:", k)
    return k*x

k = 20
multiplicator(4)
print("Значение внешней переменной k:", k)

Добавив выделенные жирными строки (global k и k = 2), мы сообщаем анализатору Python, что не намерены создавать локальную переменную k: мы просто модифицируем глобальную переменную.

7. Рекурсивные функции

В разделе про python def function мы упоминали, что функцию можно вызывать, находясь внутри другой функции. Оказывается, функция может вызывать саму себя внутри своего же исходного кода.

def factorial(x):
    #условие окончания рекурсии
    if x == 1:
        return 1
    else:
        return (x * factorial(x-1))

num = 3
print("Факториал числа", num, "равен", factorial(num))

Такие функции называют рекурсивными. В данном случае factorial(x) один раз вызывается из внешней программы и два раза — из самой себя. Перед каждым из двух этих вызовов значение аргумента x уменьшается на 1. Это происходит до тех пор, пока x не достигнет значения, равного 1. Это так называемое условие окончания рекурсии.

Программа отработает и выведет соответствующее сообщение:

Факториал числа 3 равен 6

Последовательность вычислений можно представить в хронологическом порядке:

Операция Значение x Состояние программы Условие окончания рекурсии
factorial(3) 3 первый вызов функции не выполнено
3 * factorial(2) 2 второй вызов, погружение в рекурсию не выполнено
3 * (2 * factorial(1))  1 третий вызов, погружение в рекурсию не выполнено
3 * (2 * 1)    1 выход из рекурсии (всплываем) выполнено
return 3 * 2 2 выход из рекурсии выполнено
6 3 возвращение результата выполнено

8. Анонимные функции (инструкция lambda)

Их также называют лямбда-функциями (это отсылка к математическому инструментарию под названием Лямбда Исчисление). Ключевое отличие анонимных от именных функций, казалось бы, заложено в их названиях. Но это не совсем так.

Во-первых, синтаксис функций отличается кардинально:

lambda аргументы: выражение

Во-вторых, лямбда-функция может выполнить только одну инструкцию (действие).

Для чего тогда нам нужны такие узкоспециализированные функции?

Анонимные функции идеально подходят, если нужно передать функцию в другую функцию в качестве аргумента. И если больше нигде переданная функция не будет вызвана — имя ей не понадобится. Ну и требование выполнять только одно действие (вычислять лишь одно выражение) здесь тоже играет в плюс, так как делает код более лаконичным.

Пример 1:

l = [2, 5, 1, 4]
l.sort(key=lambda x: x)

Результат работы

[1, 2, 4, 5]

Пример 2:

l = [2, 5, 1, 4]
l.sort(key=lambda x: -x)

Результат работы

[5, 4, 2, 1]

В первом примере список будет отсортирован по своим исходным (не измененным) значениям. Во втором примере лямбда-функция подставит вместо каждого элемента списка это же число, но со знаком минус. В результате список будет отсортирован в обратном порядке.

Важно также отметить, что лямбда-функции не используют инструкцию return, но всегда возвращают результат. В одном из наших примеров это результат вычисления выражения -x.

9. Присвоение функции переменной

Присвоение анонимной функции

Будет очень в тему еще один пример с анонимной функцией:

double = lambda x: x * 2

В данном случае мы просто присвоили имя этой лямбда-функции, но не вызвали ее. Этот код эквивалентен вот такой реализации именной функции:

def double(x):
print(x * 2)
return x * 2

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

double(3)

Присвоение именной функции

Хорошо, а какие чудеса мы сможем сотворить, если запишем в переменную именную функцию? Для примера создадим вот такую функцию:

def f():
print("I am f")

Зададимся целью ввести такую переменную g, чтобы

  • g() запускал вызов функции f
  • с печатью строки I am f

Первый способ

def f():
    print("I am f")


# присваивание
g = f
# вызов функции
g()

Это работает, потому что благодаря присваиванию переменная g указывает на тот же участок памяти (блок кода), что и функция f. А значит, подставив к g скобки, мы получим обычный вызов функции.

Второй способ

Используем так называемую лямбда-обертку. Создадим лямбда-функцию без аргументов, с возвращаемым значением в виде f() и запишем ее в переменную g (примерно так мы делали в начале раздела).

def f():
    print("I am f")

# лямбда-обертка
g = lambda : f()
# вызов функции
g()

Это будет работать так же, так как лямбда-функция, записанная в переменную g запустится (то есть отправит на выполнение инструкцию f()) только после выполнения инструкции g()

Заключение

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

Больше деталей и примеров можно найти тут:

Видео: про аргументы

Видео: примеры использования функции map()

  • Как пишется фронт офис
  • Как пишется фри фаер по английски
  • Как пишется фрея на английском
  • Как пишется фреш по английски
  • Как пишется френч пресс