Функции в Python
В предыдущих разделах мы уже часто сталкивались с встроенными функция ( 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 ('bmw', 'x5', 51345)
Продается Bmw X5 с пробегом 51345 км.
В данной функции видно, что должно передаваться три аргумента название автомобиля ( car_brend), модель (car_model) и пробег (mileage) . При вызове функции мы должны передать аргументы именно в том порядке, в каком они сохраняются в функции. Если нарушить порядок следования аргументов, то при вызове возможны неожиданные результаты или ошибки.
2.2. Именованные аргументы
Если порядок передачи аргументов по каким то причинам не известен, то можно использовать именованные аргументы. Именованный аргумент представляет собой пару "имя-значение". Имя и значения связываются с аргументом напрямую, так что при передаче аргумента путаница исключается. Вызовем туже самую функцию car() с помощью именованных аргументов:
>>> def car (car_brend, car_model, mileage):
. """Выводит информацию о автомобиле"""
. print(f"Продается
.
>>> car (mileage = 45152, car_model = 'x5', car_brend='bmw')
Продается Bmw X5 с пробегом 45152 км.
При обработке вызова функции Python знает к какому аргументу принадлежат данные и проблем с выводом не случается.
2.3. Значения по умолчанию
Для каждого параметра функции можно определить значение по умолчанию. Если при вызове функции не был передан аргумент, то используется значение по умолчанию. Все значение по умолчанию всегда должны следовать после параметров, у которых значений по умолчанию нет. Приведем пример той же функции, но тип автомобиля будем использовать по умолчанию
>>> car ('m5' , 56148)
Продается Bmv M5 с пробегом 56148 км.
Для изменения значения по умолчанию, мы можем передать именованный аргумент для изменения значения car_brend='audi':
>>> car ('q7', 35600, car_brend='audi')
Продается Audi Q7 с пробегом 35600 км.
Так как аргумент для параметра car_brend задан явно, Python игнорирует значение по умолчанию.
2.4. Передача произвольного набора аргументов
Иногда заранее не известно сколько аргументов должно быть передано функции, Python позволяет получить произвольное количество аргументов из вызывающей команды. Рассмотрим функцию, которая просто передает любое количество аргументов, к примеру название автомобилей:
Звездочка в имени параметра args приказывает создать Python пустой кортеж с именем args и упаковать в него все полученные результаты и с помощью команды print вывести на экран. В примере видно, что функция работает и при передаче четырех и при передаче одного аргумента.
Для более удобной работы с данными, например изменения регистра символов можно воспользоваться циклом for:
2.5. Позиционные аргументы с произвольным набором аргументов
В случае, когда в функции есть позиционные аргументы и произвольные, параметр получения произвольного количества аргументов должен стоять на последнем месте. Python сначала подберет соответствия для позиционных и именных аргументов, а потом объединит все остальные аргументы в последний параметр colors:
В результате данная функция получает два позиционных аргумента 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)
Функция 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"
. 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"
. 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. Возвращение словаря
Функция может возвращать и более сложную структуру данных, например словарь или список. Напишем функцию, которая будет возвращать словарь, представляющий человека:
При вызове функции info_person получает имя и фамилию на входе и помещает их сразу в словарь, с ключами имя и фамилия. Затем с помощью команды return возвращает словарь. В будущем со словарем будет удобнее работать, мы сможем отдельно использовать имя, фамилию или другие аргументы функции.
4. Использования функции в цикле while
Функции могут вызываться в циклах while где угодно. Приведем пример цикла while, где у посетителя запрашивают имя и фамилию, а с помощью функции form_name возвращается отформатированное имя и фамилия с приветствием:
def form_name (first_name, last_name):
"""Возвращает отформатированное полное имя"""
full_name = f"
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Добрый день
В данном примере в цикле 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
Таким образом любая простая функция в форме
может быть выражена в более компактной форме посредством лямбда-выражения
Покоряем Python — уроки для начинающих
• Аргументы передаются через автоматическое присваивание объектов локальным переменным (передача по указателям).
• Операция присваивания именам аргументов внутри функции не оказывает влияния на вызывающую программу.
• Изменение внутри функции аргумента, который является изменяемым
объектом, может оказывать влияние на вызывающую программу.
Передача аргументов очень близка к языку С:
• Неизменяемые объекты передаются «по значению». Такие объекты, как целые числа и строки, передаются в виде ссылок на объекты, а не в виде копий объектов.
• Изменяемые объекты передаются «по указателю». Такие объекты, как списки и словари, также передаются в виде ссылок на объекты, что очень похоже на то, как в языке C передаются указатели на массивы, – изменяемые объекты допускают возможность непосредственного изменения внутри функции так же, как и массивы в языке C.
Пример:
>>> def f(a): # Имени a присваивается переданный объект
. a = 99 # Изменяется только локальная переменная
.
>>> b = 88
>>> f(b)# Первоначально имена a и b ссылаются на одно и то же число 88
>>> print(b) # Переменная b не изменилась
88
В этом фрагменте в момент вызова функции f(b) переменной a присваивается объект 88, но переменная a существует только внутри вызванной функции. Изменение переменной a внутри функции не оказывает влияния на окружение, откуда была вызвана функция, – просто в момент вызова создается совершенно новый объект a .
——————————————————————
Когда в аргументах передаются изменяемые объекты, такие как списки и словари, мы должны понимать, что непосредственные изменения в таких объектах никуда не исчезнут после завершения функции и тем самым могут оказывать влияние на вызывающую программу. Ниже приводится пример, который демонстрирует эту особенность:
При попытке изменения кортежа будет возбуждено исключение:
L = [1, 2]
changer(X, tuple(L)) # Передается кортеж, поэтому попытка изменения
# возбудит исключение
Здесь используется встроенная функция tuple , которая создает новый кортеж из всех элементов последовательности (в действительности – любого итерируе мого объекта). Это особенно важно, потому что вынуждает писать функцию так, чтобы она никогда не пыталась изменять передаваемые ей аргументы. Од нако такое решение накладывает на функцию больше ограничений, чем следу ет, поэтому его вообще следует избегать (нельзя знать заранее, когда изменение аргументов окажется необходимым). Кроме того, при таком подходе функция
теряет возможность применять к аргументу методы списков, включая методы,
которые не производят непосредственных изменений.
Имитация выходных параметров:
Мы уже обсудили инструкцию return и использовали ее в нескольких примерах. Эта инструкция может возвращать объект любого типа, поэтому с ее помощью можно возвращать сразу несколько значений, упаковав их в кортеж или в коллекцию любого другого типа.
>>> def multiple(x, y):
. x = 2 # Изменяется только локальное имя
. y = [3, 4]
. return x, y # Новые значения возвращаются в виде кортежа
.
>>> X = 1
>>> L = [1, 2]
>>> X, L = multiple(X, L) # Результаты присваиваются именам
>>> X, L # в вызывающей программе
(2, [3, 4])
Синтаксис сопоставления, синтаксис использования специальных режимов сопоставления:
func(value)- Вызывающая программа — Обычный аргумент: сопоставление производится по позиции
func(name=value) — Вызывающая программа — Именованный аргумент: сопоставление производится по указанному имени
func(*sequence) — Вызывающая программа — Все объекты в указанной последовательности передаются как отдельные позиционные аргументы
func(**dict) — Вызывающая программа — Все пары ключ/значение в указанном словаре передаются как отдельные именованные аргументы
def func(name) — Функция — Обычный аргумент: сопоставление производится по позиции
или по имени
def func(name=value) — Функция — Значение аргумента по умолчанию, на случай, если аргумент не передается функции
def func(*name) — Функция — Определяет и объединяет все дополнительные аргументы
в кортеж
def func(**name) — Функция — Определяет и объединяет все
дополнительные именованные аргументы в словарь
def func(*args, name)
def func(*, name=value) — Функция — Аргументы, которые должны передаваться функции только по именам (3.0).
Случаи вызова функции и определения функции:
• В инструкции вызова функции (первые четыре строки таблицы) при использовании простых значений соответствие именам аргументов определяется по позиции, но при использовании формы name=value соответствие определяется по именам аргументов – это называется передачей именованных аргументов. Использование форм *sequence и **dict в вызовах функций позволяет передавать произвольное число объектов по позиции или по именам в виде последовательностей и словарей соответственно.
• В заголовке функции (остальная часть таблицы) при использовании простых значений соответствие определяется по позиции или по имени, в зависимости от того, как вызывающая программа передает значения, но при использовании формы name=value определяются значения по умолчанию. При использовании формы *name все дополнительные позиционные аргументы объединяются в кортеж, а при использовании формы **name все дополнительные именованные аргументы объединяются в словарь. В версии Python 3.0 и выше любые обычные аргументы или аргументы со значениями по умолчанию, следующие за формой *name или за единственным символом * , являются именованными аргументами, которые при вызове функции должны передаваться только по имени.
Массивы Python
Основы
В Питоне нет структуры данных, полностью соответствующей массиву. Однако, есть списки, которые являются их надмножеством, то есть это те же массивы, но с расширенным функционалом. Эти структуры удобнее в использовании, но цена такого удобства, как всегда, производительность и потребляемые ресурсы. И массив, и список – это упорядоченные коллекции, но разница между ними заключается в том, что классический массив должен содержать элементы только одного типа, а список Python может содержать любые элементы.
Создание массива
Существует несколько способ создать массив. Ниже приведены примеры как это можно сделать.
Многомерный массив
Двухмерный массив в Python можно объявить следующим образом.
Операции с массивами
Давайте теперь рассмотрим операции, которые Пайтон позволяет выполнять над массивами.
Обход массива с использованием цикла for
Мы можем использовать цикл for для обхода элементов массива.
Обход многомерного массива
Для того чтоб получить элементы многомерного массива придётся использовать вложенные циклы.
Добавление
Мы можем использовать функцию insert() для вставки элемента по указанному индексу. Элементы из указанного индекса сдвигаются вправо на одну позицию.
Определение размера
Используйте метод len() чтобы вернуть длину массива (число элементов массива).
Не стоит путать размер массива с его размерностью!
Срез Python предоставляет особый способ создания массива из другого массива.
Функция pop
В Python удалить ненужные элементы из массива можно при помощи метода pop, аргументом которого является индекс ячейки. Как и в случае с добавлением нового элемента, метод необходимо вызвать через ранее созданный объект.
Методы массива
В Python есть набор встроенных методов, которые вы можете использовать при работе с list.
Метод | Значение |
append() | Добавляет элементы в конец списка |
clear() | Удаляет все элементы в списке |
copy() | Возвращает копию списка |
count() | Возвращает число элементов с определенным значением |
extend() | Добавляет элементы списка в конец текущего списка |
index() | Возвращает индекс первого элемента с определенным значением |
insert() | Добавляет элемент в определенную позицию |
pop() | Удаляет элемент по индексу |
remove() | Убирает элементы по значению |
reverse() | Разворачивает порядок в списке |
sort() | Сортирует список |
Модуль array
Если Вам всё-таки нужен именно классический массив, вы можете использовать встроенный модуль array. Он почти не отличается от структуры list, за исключением, пожалуй, объявления.
Вот небольшая демонстрация: