Списки (list). функции и методы списков
Содержание:
- Примеры поиска максимального значения в последовательности.
- 3 Логарифмические функции
- Модуль functools
- Сравнение функции с методом
- Функция внутри функции в Python
- Когда лучше использовать lambda-функцию в Python?
- Функции, которые когда-нибудь можно выучить
- Типы
- Прохождение по списку
- Карринг
- Создание Shadow DOM
- 5 функций для отладки
- Подготавливаем стены
- Передача аргументов функции
- Рекурсивная функция Python
- float
- Конструктор классов с наследованием
- Язык Python функции
- Арифметические операторы
- Аргументы
- Функции придают программе структуру
Примеры поиска максимального значения в последовательности.
- ;
- ;
- ;
- ;
- ;
- .
# использование позиционных аргументов >>> max(5, 3, 6, 5, 6) # 6 # использование в качестве аргумента - список >>> max() # 5.52 # комбинирование позиционных аргументов и списка # при передаче списка 'x' происходит его распаковка >>> x = (1.2, 1.3, 1.5, 2, 5.52) >>> max(5, 3, 5, *x) # 5,52
Нахождение самой длинной строки в списке строк.
Найдем самую длинную строку. В качестве ключевой функции используем . Она посчитает количество символов в строке каждого элемента списка строк, а функция выберет максимальное число. Строки можно передать например как позиционные аргументы, так и списком , результат будет тот же.
>>> line = 'Jul', 'John', 'Vicky' >>> max(line, key=len) # 'Vicky'
Нахождение в списке строк, записанных как целые числа.
Есть список строк чисел и необходимо найти максимум, как если бы они были целыми числами? Если применить функцию к исходному списку «как есть», то она выберет наибольшее значение списка исходя из лексикографической сортировки. Для нахождения максимума, как числа, применим функцию в качестве ключа , которая «на лету» преобразует элементы списка в целые числа, тогда функция выберет то что нам нужно.
>>> x = '4', '11', '6', '31' >>> max(x) # '6' >>> max(x, key = lambda i int(i)) # '31'
Нахождения в строке, которая состоит из чисел и строк.
Что бы найти максимум в строке, которая состоит из чисел и строк, необходимо сначала разделить исходную строку на список подстрок. Используем приемы, описанные в примерах функции :
- по разделителю, например пробелу или методом строки ,
- вытащить все цифры из исходной строки при помощи функцией .
Затем в цикле перебрать полученный список и все строки с цифрами преобразовать в соответствующие числовые типы и уже потом применить функцию
# исходная строка
>>> line = '12; 12,5; 14; один; 15.6; два'
# способы преобразования строки в список строк
# 1 способ по разделителю ';'
>>> line.split(';')
#
# 2 способ по регулярному выражению
>>> import re
>>> match = re.findall(r'+', line)
>>> list(match)
#
Далее будем работать с более сложным списком, полученным 1 способом, где встречаются слова. И так, имеем список строк с цифрами и другими строками. Стоит задача: преобразовать строки с цифрами в соответствующие числовые типы и отбросить строки со словами, что бы потом найти максимум.
Задача усложняется тем, что вещественные числа в строках записаны как через запятую, так и через точку. Для необходимых проверок и преобразований определим функцию .
>>> def str_to_num(str, chars='.', ',']):
... # убираем начальные и конечные пробелы
... str = str.strip()
... if (any(char in str for char in chars) and
... str.replace('.', '').replace(',', '').isdigit()):
... # если в строке есть точка или запятая и при их замене на ''
... # строка состоит только из цифр то это тип float
... return float(str.replace(',', '.'))
... elif str.isdigit():
... # если строка состоит только из цифр то это тип int
... return int(str)
# полученный список строк 1-м способом
>>> str_list = '12', ' 12,5', ' 14', ' один', ' 15.6', ' два'
# новый список чисел, где будем искать максимум
>>> num_list = []
>>> for i in str_list
... # применим функцию преобразования строки в число
... n = str_to_num(i)
... if n is not None
... # если функция возвращает число,
... # то добавляем в новый список
... num_list.append(str_to_num(i))
>>> num_list
#
>>> max(num_list)
# 15.6
Нахождение для ключа или значения в словаре .
Допустим есть словарь, задача: найти максимальное значение ключа или самого значения ключа и вывести эту пару.
# имеем словарь
>>> d = {1 3, 2 4, 1 9, 4 1}
# преобразуем его в список отображение
>>> key_val = d.items()
# преобразуем отображение в список
# кортежей (ключ, значение)
>>> key_val_list = list(key_val)
#
По умолчанию, при нахождении максимального элемента из списка кортежей будет выбираться кортеж, у которого наибольшее значение имеет ключ исходного словаря (первый элемент в кортеже).
Но если необходимо получить пару , у которого наибольшее значение имеет значение ключа (второй элемент), то для этого нужно применить лямбда-функцию в качестве аргумента функции , которая укажет, из какого элемента кортежа выбирать наибольшее значение.
# происходит сравнение по # первым элементам кортежа >>> kv = max(key_val_list) >>> kv # (4, 1) # максимальное значение ключа в словаре >>> kv # 4 # меняем порядок сравнения >>> kv = max(key_val_list, key=lambda i i1]) >>> kv # (1, 9) # максимальное значение в словаре >>> kv1 # 9 # ключ этого значения в словаре >>> kv # 1 # получаем максимальное значение из словаря >>> dkv]] # 9
Нахождение списка с наибольшей суммой элементов в списке списков.
# исходный список >>> lst = , 4, 5], 1, 3, 4, 5], 10, 20]] # выбираем список с наибольшей суммой элементов >>> max(lst, key=sum) #
3 Логарифмические функции
Модуль предоставляет нам следующие функции для вычисления логарифмических значений чисел с десятичной запятой:
- decimal.ln();
- decimal.log10().
Функция возвращает значение натурального десятичного числа, как показано ниже.
decimal.Decimal(decimal-number).ln()
Функция decimal.log10() используется для вычисления значения журнала по основанию 10 переданного ей десятичного числа.
decimal.Decimal(decimal-number).log10()
Пример:
import decimal as d
d.getcontext().prec = 2
val = d.Decimal(122.20)
log = val.ln()
print("Natural log value of the decimal number: ",log)
log_10 = val.log10()
print("Log value with base 10 of the decimal number: ",log_10)
Выход:
Natural log value of the decimal number: 4.8 Log value with base 10 of the decimal number: 2.1
Модуль functools
Functools – это библиотека, которая содержит дополнительные функции высших порядков. Подключай и используй.
reduce()
Принимает функцию и последовательность. Запускает цепь вычислений, применяя функцию ко всем элементам последовательности. Сводит набор к единственному значению.
С помощью можно делать так:
lru_cache
Это – декоратор. То есть «обёртка», которая может изменить поведение функции, не меняя её код. Lru_cache даёт выбранной функции кэширование, чтобы фиксировать результаты тяжеловесных вычислений, запросов или других операций.
update_wrapper
Используется для обновления метаданных функции-обертки, данными из некоторых атрибутов оборачиваемой функции. Обеспечивает лучшую читаемость и возможность повторного использования кода.
wraps
wraps – это ещё один декоратор. Он применяется к функции-обертке. wraps обновляет функцию-обертку так, чтобы она выглядела как оборачиваемая функция. При этом копируются атрибуты и .
Сравнение функции с методом
- Функция Python является частью файла сценария Python, в котором она определена, тогда как методы определены внутри определения класса.
- Мы можем вызвать функцию напрямую, если она находится в том же модуле. Если функция определена в другом модуле, мы можем импортировать модуль, а затем вызвать функцию напрямую. Нам нужен класс или объект класса для вызова методов.
- Функция Python может обращаться ко всем глобальным переменным, тогда как методы класса Python могут обращаться к глобальным переменным, а также к атрибутам и функциям класса.
- Тип данных функций Python — это «функция», а тип данных методов Python — «метод».
Давайте посмотрим на простой пример функций и методов в Python.
class Data:
def foo(self):
print('foo method')
def foo():
print('foo function')
# calling a function
foo()
# calling a method
d = Data()
d.foo()
# checking data types
print(type(foo))
print(type(d.foo))
Вывод:
foo function foo method <class 'function'> <class 'method'>
Преимущества
- Возможность повторного использования кода, потому что мы можем вызывать одну и ту же функцию несколько раз
- Модульный код, поскольку мы можем определять разные функции для разных задач
- Улучшает ремонтопригодность кода
- Абстракция, поскольку вызывающему абоненту не нужно знать реализацию функции
Функция внутри функции в Python
Функции в Python мы можем создавать, вызывать и возвращать из других функций. Кстати, на этом основана идея замыкания (closures) в Python.
Давайте создадим функцию, умножающую 2 числа:
def mul(a): def helper(b): return a * b return helper
В этой функции в Python реализованы два важных свойства:
1) внутри функции mul() мы создаём ещё одну функцию helper();
2) функция mul() возвращает нам функцию helper() в качестве результата работы.
Вызов этой функции в Python:
>>>mul(4)(2) 8
Особенность заключается в том, что мы можем создавать на базе функции mul() собственные кастомизированные функции. Давайте создадим функцию в Python, умножающую на 3:
>>>three_mul = mul(3) >>>three_mul(5) 15
В результате была построена функция three_mul(), умножающая на 3 любое переданное ей число.
Когда лучше использовать lambda-функцию в Python?
Как мы видели ранее, lambda-функция в Python может принимать несколько аргументов и одно выражение. Причем значение этого выражения как раз и есть то, что возвращается при вызове функции. Использование lambda-функций не является обязательным, но может оказаться полезным в определенных ситуациях. Таких, например как:
1. Когда у вас есть только одно выражение для исполнения в функции
Допустим, мы хотим для функции printhello() запрограммировать вывод на экран слова «Привет». Тогда в теле функции у нас будет всего одна строчка:
def printhello():
print("Привет")
printhello()
Привет
Теперь давайте сделаем то же самое, используя lambda-функцию.
(lambda :print("Привет"))()
Привет
Заметьте, что здесь мы не использовали никаких аргументов. Но вернемся и более подробно рассмотрим мы этот момент в дальнейшем, а пока давайте обратимся к еще одному примеру.
z=lambda a=2:print("Hello")
z()
Привет
2. Когда нужно вызвать код только один раз
Одной из основных причин выделения функций из остального кода является необходимость в их многократном использовании. Но если вам нужно использовать какой-либо код не более чем один раз, вы можете прибегнуть к lambda-функциям, не объявляя для этого стандартную функцию.
Функции, которые когда-нибудь можно выучить
Следующие встроенные функции Python определённо не бесполезны, но они более специализированы.
Эти функции вам, возможно, будут нужны, но также есть шанс, что вы никогда не прибегнете к ним в своём коде.
- : возвращает итератор (список, набор и т. д.);
- : возвращает , если аргумент является вызываемым;
- and : вместо них рекомендуется использовать генератор-выражения;
- : округляет число;
- : эта функция выполняет деление без остатка () и операцию по модулю () одновременно;
- , и : служат для отображения чисел в виде строки в двоичной, восьмеричной или шестнадцатеричной форме;
- : возвращает абсолютное значение числа (аргумент может быть целым или числом с плавающей запятой, если аргумент является комплексным числом, его величина возвращается);
- ;
- .
Типы
В Python есть два типа функций.
- встроенные: функции, предоставляемые языком Python, такие как print (), len (), str () и т. д.
- пользовательские: функции, определенные нами в программе Python.
Может ли функция иметь значение параметра по умолчанию?
Python допускает значения по умолчанию для параметров функции. Если вызывающий абонент не передает параметр, используется значение по умолчанию.
def hello(year=2019):
print(f'Hello World {year}')
hello(2020) # function parameter is passed
hello() # function parameter is not passed, so default value will be used
Вывод:
Hello World 2020 Hello World 2019
Можем ли мы иметь несколько операторов возврата внутри функции?
Да, функция может иметь несколько операторов возврата. Однако при достижении одного из операторов возврата выполнение функции прекращается, и значение возвращается вызывающей стороне.
def odd_even_checker(i):
if i % 2 == 0:
return 'even'
else:
return 'odd'
print(odd_even_checker(20))
print(odd_even_checker(15))
Может ли функция Python возвращать несколько значений одно за другим?
Функция Python может возвращать несколько значений одно за другим. Это реализовано с использованием ключевого слова yield. Это полезно, когда вы хотите, чтобы функция возвращала большое количество значений и обрабатывала их. Мы можем разделить возвращаемые значения на несколько частей, используя оператор yield. Этот тип функции также называется функцией генератора.
def return_odd_ints(i):
x = 1
while x <= i:
yield x
x += 2
output = return_odd_ints(10)
for out in output:
print(out)
Вывод:
1 3 5 7 9
Прохождение по списку
enumerate(iterable )
Возвращает генератор, отдающий пары счётчик(индекс)-элемент для указанного итерируемого объекта.
Параметры:
— последовательность, итератор или объекты, поддерживающие итерирование.
– значение, с которого начинается отсчет. Необязательный аргумент, по умолчанию равен нулю.
Возвращаемое значение:
enumerate object — генератор, отдающий пары счётчик(индекс)-элемент для указанного итерируемого объекта.
Примечание:
Вы можете преобразовать enumerate object в список или кортеж, используя функции и соответственно.
Примеры:
Пример 1: Работа с .
grocery = enumerateGrocery = enumerate(grocery) # <class 'enumerate'> print(type(enumerateGrocery)) # print(list(enumerateGrocery)) enumerateGrocery = enumerate(grocery, 10) # print(list(enumerateGrocery))
Пример 2: Прохождение по enumerate object.
grocery =
for item in enumerate(grocery):
print(item)
print('\n')
for count, item in enumerate(grocery):
print(count, item)
print('\n')
# изменение значения start
for count, item in enumerate(grocery, 100):
print(count, item)
Результат:(0, ‘bread’)(1, ‘milk’)(2, ‘butter’)
0 bread1 milk2 butter
100 bread101 milk102 butter
Карринг
Карринг (или каррирование, curring) — преобразование функции от многих переменных в функцию, берущую
свои аргументы по одному.
Примечание. Это преобразование было введено М. Шейнфинкелем и Г. Фреге и получило
своё название в честь математика Хаскелла Карри, в честь которого также назван и язык программирования
Haskell.
Карринг не относится к уникальным особенностям функционального программирования, так карринговое
преобразование может быть записано, например, и на языках Perl или C++. Оператор каррирования даже
встроен в некоторые языки программирования (ML, Haskell), что позволяет многоместные функции приводить к
каррированному представлению. Но все языки, поддерживающие замыкания, позволяют записывать
каррированные функции, и Python не является исключением в этом плане.
В листинге 8 представлен простейший пример с использованием карринга (файл curry1.py
в архиве python_functional.tgz в разделе «Материалы для скачивания»):
Листинг 8. Карринг
# -*- coding: utf-8 -*-
def spam( x, y ):
print( 'param1={}, param2={}'.format( x, y ) )
spam1 = lambda x : lambda y : spam( x, y )
def spam2( x ) :
def new_spam( y ) :
return spam( x, y )
return new_spam
spam1( 2 )( 3 ) # карринг
spam2( 2 )( 3 )
Вот как выглядят исполнение этих вызовов:
$ python curry1.py param1=2, param2=3 param1=2, param2=3
Создание Shadow DOM
5 функций для отладки
Эти функции часто игнорируются, но будут полезны для отладки и устранения неисправностей кода.
breakpoint
Если нужно приостановить выполнение кода и перейти в командную строку Python, эта функция вам пригодится. Вызов перебросит вас в отладчик Python.
Эта встроенная функция была добавлена в Python 3.7, но если вы работаете в более старых версиях, можете получить тот же результат с помощью .
dir
Эта функция может использоваться в двух случаях:
- просмотр списка всех локальных переменных;
- просмотр списка всех атрибутов конкретного объекта.
Из примера можно увидеть локальные переменные сразу после запуска и после создания новой переменной .
Если в передать созданный список , на выходе можно увидеть все его атрибуты.
В выведенном списке атрибутов можно увидеть его типичные методы (, , и т. д.) , а также множество более сложных методов для перегрузки операторов.
vars
Эта функция является своего рода смесью двух похожих инструментов: и .
Когда вызывается без аргументов, это эквивалентно вызову , которая показывает словарь всех локальных переменных и их значений.
Когда вызов происходит с аргументом, получает доступ к атрибуту , который представляет собой словарь всех атрибутов экземпляра.
Перед использованием было бы неплохо сначала обратиться к .
type
Эта функция возвращает тип объекта, который вы ей передаете.
Тип экземпляра класса есть сам класс.
Тип класса — это его метакласс, обычно это .
Атрибут даёт тот же результат, что и функция , но рекомендуется использовать второй вариант.
Функция , кроме отладки, иногда полезна и в реальном коде (особенно в объектно-ориентированном программировании с наследованием и пользовательскими строковыми представлениями).
Обратите внимание, что при проверке типов обычно вместо используется функция. Также стоит понимать, что в Python обычно не принято проверять типы объектов (вместо этого практикуется утиная типизация)
help
Если вы находитесь в Python Shell или делаете отладку кода с использованием , и хотите знать, как работает определённый объект, метод или атрибут, функция поможет вам.
В действительности вы, скорее всего, будете обращаться за помощью к поисковой системе. Но если вы уже находитесь в Python Shell, вызов будет быстрее, чем поиск документации в Google.
Подготавливаем стены
Передача аргументов функции
Теперь мы готовы узнать о том, как создать функцию, которая может получать доступ к аргументам, а также узнаем, как передать аргументы функции. Создадим простую функцию, которая может суммировать два числа:
Python
def add(a, b):
return a + b
print( add(1, 2) ) # 3
|
1 |
defadd(a,b) returna+b print(add(1,2))# 3 |
Каждая функция выдает определенный результат. Если вы не указываете на выдачу конкретного результата, она, тем не менее, выдаст результат None (ничего). В нашем примере мы указали выдать результат a + b. Как вы видите, мы можем вызвать функцию путем передачи двух значений. Если вы передали недостаточно, или слишком много аргументов для данной функции, вы получите ошибку:
Python
add(1)
Traceback (most recent call last):
File «<string>», line 1, in <fragment>
TypeError: add() takes exactly 2 arguments (1 given)
|
1 |
add(1) Traceback(most recent call last) File»<string>»,line1,in<fragment> TypeErroradd()takes exactly2arguments(1given) |
Вы также можете вызвать функцию, указав наименование аргументов:
Python
print( add(a = 2, b = 3) ) # 5
total = add(b = 4, a = 5)
print(total) # 9
|
1 |
print(add(a=2,b=3))# 5 total=add(b=4,a=5) print(total)# 9 |
Стоит отметить, что не важно, в каком порядке вы будете передавать аргументы функции до тех пор, как они называются корректно. Во втором примере мы назначили результат функции переменной под названием total
Это стандартный путь вызова функции в случае, если вы хотите дальше использовать её результат.
Вы, возможно, подумаете: «А что, собственно, произойдет, если мы укажем аргументы, но они названы неправильно? Это сработает?» Давайте попробуем на примере:
Python
add(c=5, d=2)
Traceback (most recent call last):
File «<string>», line 1, in <fragment>
TypeError: add() got an unexpected keyword argument ‘c’
|
1 |
add(c=5,d=2) Traceback(most recent call last) File»<string>»,line1,in<fragment> TypeErroradd()got an unexpected keywordargument’c’ |
Ошибка. Кто бы мог подумать? Это значит, что мы указали ключевой аргумент, который функция не распознала. Кстати, ключевые аргументы описана ниже.
Рекурсивная функция Python
Когда функция вызывает сама себя, она называется рекурсивной функцией. В программировании этот сценарий называется рекурсией.
Вы должны быть очень осторожны при использовании рекурсии, потому что есть вероятность, что функция никогда не завершится и перейдет в бесконечный цикл. Вот простой пример печати ряда Фибоначчи с использованием рекурсии.
def fibonacci_numbers_at_index(count):
if count <= 1:
return count
else:
return fibonacci_numbers_at_index(count - 1) + fibonacci_numbers_at_index(count - 2)
count = 5
i = 1
while i <= count:
print(fibonacci_numbers_at_index(i))
i += 1
Полезно знать о рекурсии, но в большинстве случаев при программировании это не нужно. То же самое можно сделать с помощью цикла for или while.
float
В Python, если число не является целым, оно является десятичным. Есть несколько различий между целыми и десятичными числами.
Целое число (тип данных int):
- Является целым числом;
- Не содержит десятичной точки;
- Может быть положительным, отрицательными или нулем;
Десятичное число (тип данных float):
- Может быть любым числом, которое включает десятичную точку;
- Может быть положительным и отрицательным;
Попробуйте вызвать range() с десятичным числом и увидите, что будет:
Python
for i in range(3.3):
print(i)
|
1 |
foriinrange(3.3) print(i) |
Вы увидите следующее уведомление об ошибке TypeError:
Python
Traceback (most recent call last):
File «<stdin>», line 1, in <module>
TypeError: ‘float’ object cannot be interpreted as an integer
|
1 |
Traceback(most recent call last) File»<stdin>»,line1,in<module> TypeError’float’objectcannot be interpreted asan integer |
Если вам нужен обходной путь, который позволит вам использовать десятичные числа, вы можете использовать NumPy.
Конструктор классов с наследованием
class Person:
def __init__(self, n):
print('Person Constructor')
self.name = n
class Employee(Person):
def __init__(self, i, n):
print('Employee Constructor')
super().__init__(n) # same as Person.__init__(self, n)
self.id = i
emp = Employee(99, 'Pankaj')
print(f'Employee ID is {emp.id} and Name is {emp.name}')
Выход:
Employee Constructor Person Constructor Employee ID is 99 and Name is Pankaj
- Мы обязаны вызвать конструктор суперкласса.
- Мы можем использовать функцию super() для вызова функции конструктора суперкласса.
- Мы также можем использовать имя суперкласса для вызова его метода init().
Язык Python функции
Часть функций языка Python являются встроенными функциями, которые обеспечены синтаксисом самого языка. Например, int, input, randint.
Рассмотрим пример создания пользовательских функций.
- Функция — это поименованный фрагмент программы, который можно вызвать.
- Как и процедура, функция должна быть определена к моменту её вызова (служебное слово def).
- Функция в отличии от процедуры возвращает значение.
- Для возврата значения функции используется оператор return.
- Вызов функции осуществляется по ее имени и обычно сопровождается выводом значения.
Пример:
Найти максимальное значение из значений двух переменных.
Решение:
def max(a,b):
if(a>b):
return a
else:
return b
x=int(input())
y=int(input())
print('max = ',max(x,y))
|
Задание Python 3_6:
Создайте функцию для поиска минимума среди трех чисел (три параметра функции).
Пример:
Вычислить сумму цифр числа.
1 2 3 4 5 6 7 8 |
def sumD(n): # определение функции с параметром
sum =
while n!= :
sum += n % 10
n = n // 10
return sum # возврат значения функции
# основная программа
print (sumD(1075)) # вызов функции с параметром
|
Задание Python 3_7:
Напишите функцию, которая вычисляет количество цифр числа.
Задание Python 3_8:
Создайте функцию, которая вычисляет сумму всех чисел от до . — параметр функции.
Задание Python 3_9:
Напишите функцию, которая вычисляет факториал натурального числа N.
Арифметические операторы
Арифметические операторы обычно работают с числами. Есть операторы для сложения, вычитания, умножения, деления, модуля и экспоненциальных операций. Некоторые из этих операторов работают и со строками. Все арифметические операторы — специальные символы.
- +: оператор сложения;
- -: оператор вычитания;
- *: оператор умножения;
- /: оператор деления;
- **: экспоненциальный оператор;
- //: оператор деления этажей.
Давайте посмотрим на пример арифметических операторов в Python.
x = 15
y = 7
sum = x + y
print("addition =", sum)
subtraction = x - y
print("subtraction =", subtraction)
multiplication = x * y
print("multiplication =", multiplication)
division = x / y
print("division =", division)
modulus = x % y
print("modulus =", modulus)
exponent = x ** 2
print("exponent =", exponent)
floor_division = x // y
print("division =", floor_division) # 2
Вывод:

Python поддерживает операторы сложения и умножения для строк.
print("addition of strings =", ("Python" + " " + "Operators"))
print("multiplication of strings =", ("Python" * 2))
Вывод:
addition of strings = Python Operators multiplication of strings = PythonPython
Аргументы
Позиционные
Вспомним, аргумент – это конкретное значение, которое передаётся в функцию. Аргументом может быть любой объект. Он может передаваться, как в литеральной форме, так и в виде переменной.
Значения в позиционных аргументах подставляются согласно позиции имён аргументов:
Именованные
Пусть есть функция, принимающая три аргумента, а затем выводящая их на экран. Python позволяет явно задавать соответствия между значениями и именами аргументов.
При вызове соответствие будет определяться по именам, а не по позициям аргументов:
Необязательные параметры (параметры по умолчанию)
Python позволяет делать отдельные параметры функции необязательными. Если при вызове значение такого аргумента не передается, то ему будет присвоено значение по умолчанию.
Аргументы переменной длины (args, kwargs)
Когда заранее неизвестно, сколько конкретно аргументов будет передано в функцию, мы пользуемся аргументами переменной длины. Звёздочка «*» перед именем параметра сообщает интерпретатору о том, что количество позиционных аргументов будет переменным:
Переменная составляет кортеж из переданных в функцию аргументов.
Функции в питоне могут также принимать и переменное количество именованных аргументов. В этом случае перед названием параметра ставится «»:
Здесь kwargs уже заключает аргументы не в кортеж, а в словарь.
Если объект неизменяемый, то он передаётся в функцию по значению. Неизменяемые объекты это:
- Числовые типы (int, float, complex).
- Строки (str).
- Кортежи (tuple).
В Python изменяемые объекты это:
- Списки (list).
- Множества (set).
- Словари (dict).
Будьте внимательны при передаче изменяемых объектов. Одна из частых проблем новичков.
В функциональном программировании существует понятие «функциями с побочными эффектами» – когда функция в процессе своей работы изменяет значения глобальных переменных. По возможности, избегать таких функций.
Функции придают программе структуру
Польза функций не только в возможности многократного вызова одного и того же кода из разных мест программы
Не менее важно, что благодаря им программа обретает истинную структуру. Функции как бы разделяют ее на обособленные части, каждая из которых выполняет свою конкретную задачу
Пусть надо написать программу, вычисляющую площади разных фигур. Пользователь указывает, площадь какой фигуры он хочет вычислить. После этого вводит исходные данные. Например, длину и ширину в случае прямоугольника. Чтобы разделить поток выполнения на несколько ветвей, следует использовать оператор if-elif-else:
figure = input("1-прямоугольник,
2-треугольник, 3-круг: ")
if figure == '1':
a = float(input("Ширина: "))
b = float(input("Высота: "))
print("Площадь: %.2f" % (a*b))
elif figure == '2':
a = float(input("Основание: "))
h = float(input("Высота: "))
print("Площадь: %.2f" % (0.5 * a * h))
elif figure == '3':
r = float(input("Радиус: "))
print("Площадь: %.2f" % (3.14 * r**2))
else:
print("Ошибка ввода")
Здесь нет никаких функций, и все прекрасно. Но напишем вариант с функциями:
def rectangle():
a = float(input("Ширина: "))
b = float(input("Высота: "))
print("Площадь: %.2f" % (a*b))
def triangle():
a = float(input("Основание: "))
h = float(input("Высота: "))
print("Площадь: %.2f" % (0.5 * a * h))
def circle():
r = float(input("Радиус: "))
print("Площадь: %.2f" % (3.14 * r**2))
figure = input("1-прямоугольник,
2-треугольник, 3-круг: ")
if figure == '1':
rectangle()
elif figure == '2':
triangle()
elif figure == '3':
circle()
else:
print("Ошибка ввода")
Он кажется сложнее, а каждая из трех функций вызывается всего один раз. Однако из общей логики программы как бы убраны и обособлены инструкции для нахождения площадей. Программа теперь состоит из отдельных «кирпичиков Лего». В основной ветке мы можем комбинировать их как угодно. Она играет роль управляющего механизма.
Если нам когда-нибудь захочется вычислять площадь треугольника по формуле Герона, а не через высоту, то не придется искать код во всей программе (представьте, что она состоит из тысяч строк кода как реальные программы). Мы пойдем к месту определения функций и изменим тело одной из них.
Если понадобиться использовать эти функции в какой-нибудь другой программе, то мы сможем импортировать их туда, сославшись на данный файл с кодом (как это делается в Python, будет рассмотрено позже).





