l4.ppt
- Количество слайдов: 105
НИР/НИС Процедуры, функции высшего порядка
Процедура • Процедура – имеющая собственное имя часть программы, которая при вызове может получать параметры, выполняет некоторые действия, изменяющие окружение, и возвращает управление в точку вызова.
Функция • Функция – имеющая собственное имя часть программы, при вызове получает параметры, и в соответствии с ними возвращает свое значение, не меняя окружение.
Смешанный подход • Pascal: функции могут изменять окружение • C: любая подпрограмма это функция, но она может возвращать значение типа void (пустое), превращаясь таким образом в «процедуру» • Ассемблер: возврат управления не в точку вызова.
Объявление процедур и функции однотипно def NAME( LIST OF PARAMETERS ): STATEMENTS Блок функции формируется отступами Значение возвращается либо явно (через return), либо неявно (None)
Использование • • Вынос повторяемого кода в функцию Улучшение читаемости Повторное использование кода Уменьшение размера кода Структурирование кода Настраиваемость функций Формирование модулей
Вызов • Использование функции или процедуры в коде происходит через упоминание ее имени • Вызов функции/процедуры передает ей управление • После окончания работы управление передается в точку вызова
def new. Line(): print "First Line. " new. Line() print "Second Line. "
def new. Line(): print def three. New. Lines(): new. Line() print "First Line. " three. New. Lines() print "Second Line. "
Возвращение значения • Функция возвращает значение (результат) • Значение функции может быть сохранено в переменную >>> betty = type("32") >>> print betty
Параметры и аргументы • Параметр – в объявлении функции. • Объявление процедуры/функции определяет ее структуру и внутренние переменные • Аргумент – при вызове • Аргументом может быть – Переменная – Значение – Результат вычисления или другой функции
Параметры и аргументы def print. Twice(bruce): print bruce, bruce >>>print. Twice(’Sam’) Sam >>> print. Twice(5) 55 >>> print. Twice(3. 14159) 3. 14159 С 1 параметром Вызов с аргументом ‘Sam’ Вызов с аргументом 5 Вызов с аргументом 3. 14159
Имена • При вызове процедур/функций создаются временные переменные с именами, указанным в параметрах • Им присваиваются значения аргументов или ссылки на них • После завершения работы такие временные переменные удаляются • При каждом вызове процедуры/функции они инициализируется заново
Глобальные и локальные переменные • Глобальные переменные – переменные объявленные для всей программы целиком • Локальные существуют только в определенном блоке кода и не доступны в других блоках
Параметры переменных/функций • Переменные с именем параметра локальны • При совпадении имен они перекрывают соответствующие глобальные переменные, которые становятся не доступны • Глобальные из функций доступны на чтение • Для модификации их нужно «объявить» внутри функции с ключевым словом global
Например, def print. Both(a, b): print a, b a=5 b=6 c=7 d=8 print. Both(a, d) print. Both(b, c) a-глоб. b-глоб. 5 6 c-глоб. d-глоб. 7 8
Например, def print. Both(a, b): print a, b a=5 b=6 c=7 d=8 print. Both(a, d) print. Both(b, c) a-глоб. 5 b-глоб. 6 a-лок. b-лок 5 8 c-глоб. d-глоб. 7 8
Например, def print. Both(a, b): print a, b a=5 b=6 c=7 d=8 print. Both(a, d) print. Both(b, c) a-глоб. 5 b-глоб. 6 a-лок. b-лок 6 7 c-глоб. d-глоб. 7 8
Передача по значению/ссылке • Неизменяемые типы передаются по значению • Изменяемые – по ссылке – Но тип их изменить не даст
Возврат значения • Оператор return – Позволяет вернуть значение из функции – Позволяет управлять выполнением • По оператору return осуществляется возврат и значения, и управления из функции • Операторы в теле функции после оператора return не выполняются
def Sum(a, b): return a+b a=1 c=7 d = Sum(a, c) print d Output: 8
Возврат множества значений • Функция может возвращать несколько значений, перечисленных через запятую – они будут возвращены как кортеж. def powers(x): return x*x, x*x*x*x X=powers(2) X 2, X 3, X 4=powers(3) #X (4, 8, 16) #X 2=9, X 3=27, Х 4=81
Композиция функций • Результат одной функции как параметр другой • x = math. exp(math. log(10. 0))
+ • Именованные параметры – зная имена параметров можно менять их местами • def describe. Book (author, name, quality): – print author, "'s", name, 'is a', quality, 'book. ' d. Describe. Book ('G. Booch', 'OOA&D with Applications', 'good') d. Describe. Book (quality='good', name='OOA&D with Applications', author='G. Booch')
Необязательные параметры и значения по-умолчанию def describe. Book (author, name="book", quality="bad"): print author, "'s", name, 'is a', quality, 'book. '
Параметры неизвестной длинны def describe. Authors(*several): for one in several: describe. Book (one)
def a(*args): print type(args) print args a(1, 2, 3, 4, 5) >>>
def a(*args): print args a(1, 2, 3) a([1, 2, 3]) a(*[1, 2, 3]) >>> (1, 2, 3) >>> ([1, 2, 3], ) >>> (1, 2, 3)
Произвольное количество именнованых аргументов def a(**kwargs): print kwargs a() a(b=1, c=2) >>> {} >>> {'c': 2, 'b': 1}
Передача словаря в функцию def a(**kwargs): print kwargs d = {'k 1': 1, 'k 2': 2} a(k 1=d) a(**d) >>> {'k 1': {'k 2': 2, 'k 1': 1}} >>> {'k 2': 2, 'k 1': 1} Словарь передан как один именованный аргумент. Словарь передан как произвольное количество именованных аргументов
Вызов процедур • Процедуры и функции могут вызывать друга и использовать результаты работы функций в вычислениях def change(x): return x - 1 def out(x): print change (x) out(7)
Вызов процедур • Логические выражения позволяют управлять выполнением той или иной ветви алгоритма def change(x): if x > 0: return x - 1 else: return x + 1 def out(x): print change (x) out(7) out(-7)
Локальные переменные • В ходе работы подпрограммы (процедуры или функции) для нее создаются локальные переменные, уничтожаемые при выходе из подпрограммы
• До момента завершения подпрограммы ее локальные переменные существуют и могут быть использованы
• При совпадении имен переменных, происходит скрытие части переменных • Так как в области видимости подпрограммы не может существовать двух переменных с одним именем
Рекурсия • Рекурсия: функция/процедура вызывает саму себя • Непосредственно самовызов функции называют «рекурсивным» • Количество вызовов рекурсии называют ее глубиной
• Когда в подпрограмме встречается оператор с собственным именем ничего особенного не происходит. • Вновь создаются локальные переменные и параметры и скрывают одноименные объявленные ранее. • При завершении выполнения процедур экземпляры переменных и параметров, созданные при последнем запуске процедуры исчезают, и становятся доступны одноименные копии из предыдущего запуска и выполняются операторы, следующие за процедурным оператором.
Виды рекурсии • Прямая (простая рекурсия) def recursive. Func(x): print x if x > 0: recursive. Func(x - 1) recursive. Func(5)
recursive. Func(5) -> recursive. Func(4) -> recursive. Func(3) -> recursive. Func(2) -> recursive. Func(1) -> recursive. Func(0) -> завершение recursive. Func(0) и возврат в recursive. Func(1) -> возврат в recursive. Func(2) -> возврат в recursive. Func(3) -> возврат в recursive. Func(4) -> возврат в recursive. Func(5) -> возврат в тело программы def recursive. Func(x): print x if x > 0: recursive. Func(x - 1) recursive. Func(5)
def recursive. Func(x): print x if x > 0: recursive. Func(x - 1) recursive. Func(5) OUTPUT 5 4 3 2 1 0
Виды рекурсии • Косвенная (сложная рекурсия) def A(x): print x B(x - 1) def B(x): if x > 0: print x A(x - 1)
A(5) -> B(4) -> A(3) -> B(2) -> A(1) -> B(0) -> возврат в A(1) -> возврат в B(2) -> возврат в A(3) -> возврат в B(4) -> возврат в A(5) -> возврат в тело программы def A(x): print x B(x - 1) def B(x): if x > 0: print x A(x - 1) A(5)
def A(x): print x B(x - 1) def B(x): if x > 0: print x A(x - 1) A(5) OUTPUT 5 4 3 2 1
recursive. Func(5) -> recursive. Func(4) -> recursive. Func(3) -> recursive. Func(2) -> recursive. Func(1) -> recursive. Func(0) -> возврат в recursive. Func(1) -> возврат в recursive. Func(2) -> возврат в recursive. Func(3) -> возврат в recursive. Func(4) -> возврат в recursive. Func(5) -> возврат в тело программы def recursive. Func(x): if x > 0: recursive. Func(x - 1) print x recursive. Func(5) OUTPUT 1 2 3 4 5
Последовательные повторяющиеся действия • Ctrl+C, Ctrl+V • Итеративное выполнение • Рекурсия
Применение рекурсии • Для обработки подобных данных, когда задача сводится к аналогичной, но более простой. • Полное решение задачи принимает форму рекурсивной процедуры, которая выполняет необходимые упрощения задачи, далее вызывает себя для решения более простой задачи. • Задача должна иметь тривиальное решение для определенных входных данных
Например, • Факториал числа n • n! = n * (n-1) * (n-2) * (n-3)*. . *1 • n! = n * (n-1)!, 1! = 1
Итеративное вычисление факториала n=5 factorial = 1 for i in range(1, n+1): factorial = factorial * i print factorial n i factorial 5 ? 1 5 1 1 5 2 2 5 3 6 5 4 24 5 5 120
Рекурсивное вычисление факториала def factorial(n): if n > 1: result = n * factorial(n - 1) else: result = 1 print factorial(5) result 5 5 * factorial(4) 4 4 * factorial(3) 3 3 * factorial(2) 2 2 * factorial(1) 1 1 2 2*1=2 3 3*2=6 4 return result n 4 * 6 = 24 5 5 * 24 = 120
Рекурсивное вычисление факториала def factorial(n): if n > 1: return n * factorial(n - 1) else: return 1 print factorial(5)
Бесконечная рекурсия • Так как функция вызывает саму себя, должно быть условие, при котором не произойдет рекурсивного вызова def factorial(n): if n > 1: return n * factorial(n - 1) else: return 1 Условие выхода из рекурсии: n <= 1
Бесконечная рекурсия • Условие выхода из рекурсии должно быть достижимым def factorial(n): if n > 1: return n * factorial(n + 1) else: return 1 Условие выхода из рекурсии: n <= 1
Минус рекурсивного выполнения • Сложность отслеживания • Ресурсоемкость
Функции высшего порядка
Функции высшего порядка • Принимают другие функции в виде аргументов • Возвращают функции в виде аргументов
В Питоне • Функцию (имя) можно передать в качестве аргумента
def inc 2(x): return x + 2 def inc 3(x): return x + 3 def inc_multiply(func, x, y): return func(x) * func(y) inc_multiply(inc 2, 4, 6) # результат = 48 inc_multiply(inc 3, 4, 6) # результат = 63
def inc 2(x): return x + 2 def inc 3(x): return x + 3 def inc_multiply(func, x, y): return func(x) * func(y) # func == inc 2 # == inc 2(x) * inc 2(y) inc_multiply(inc 2, 4, 6) # результат = 48 inc_multiply(inc 3, 4, 6) # результат = 63
def inc 2(x): return x + 2 def inc 3(x): return x + 3 def inc_multiply(func, x, y): return func(x) * func(y) # func == inc 3 # == inc 3(x) * inc 3(y) inc_multiply(inc 2, 4, 6) # результат = 48 inc_multiply(inc 3, 4, 6) # результат = 63
Встроенные функции высшего порядка map, filter, reduce, apply, lambda
Map • Применяет функцию к каждому элементу списка и возвращает новый список • 1 аргумент – функция (имя) без передачи параметров • 2, 3, 4 и т. д. аргументы – список, строка, кортеж – т. е. поддерживающие поэлементный перебор
Map map ( функция, список [, список])
Map >>> def squared(x): return x*x >>> map(squared, [1, 2, 3]) [1, 4, 9]
Map >>> def doublex(x): return x * 2 >>> a = [5, 6, 7, 'a', 'b', 'c'] >>> b = map(doublex, a) >>> b [10, 12, 14, 'aa', 'bb', 'cc']
Map • Т. е. map(функция, список) эквивалентна циклической обработке списка >>> a = [5, 6, 7, 'a', 'b', 'c'] >>> def doublex(x): return x * 2 c = map(doublex, a) >>> c = [] >>> for element in a: c. append(doublex(element))
Map и несколько параметров >>> def multiply(x, y): return x * y >>> a = [1, 2, 3] >>> b = [4, 5, 6] >>> map(multiply, a, b) [4, 10, 18]
Filter • Проверяет каждый элемент списка на соответствие заданному условию • Возвращает список только из тех элементов, которые этому условию удовлетворили
Filter • Если последовательность элементов на обработку — строка (string) или кортеж (tuple), результат будет иметь тот же тип • В других случаях — это всегда список.
Filter
Filter >>> def less 5(x): if x > 5: return False return True >>> filter(less 5, [1, 2, 5, 10, 3, 17, 2]) [1, 2, 5, 3, 2] filter (функция, список)
Filter >>> def short 3(x): if len(x) > 3: return False return True >>> filter(short 3, ['a', 'abc', 'abcde']) ['a', 'abc']
Filter >>> def f 23(x): return x % 2 != 0 and x % 3 != 0 >>> filter(f 23, range(2, 25)) # отфильтровать диапазон чисел # от 2 до 24 через функцию f [5, 7, 11, 13, 17, 19, 23]
Reduce • Reduce – последовательно обрабатывает элементы списка, «накапливая» результат (свертка списка) • Функция вызывается для первых двух элементов из списка, затем для результата предыдущих вычислений и третего и т. д. пока не будут обработаны все элементы списка. • Функция будет вызвана n-1 раз если список содержит n элементов.
Reduce • • Пусть требуется найти сумму чисел списка [1, 2, 3, 4, 5, 6] 1+2+3+4+5+6 (((((1 + 2) + 3) + 4) + 5) + 6)
Reduce >>> a = [1, 2, 3, 4, 5, 6] >>> def summ(x, y): return x + y >>> reduce(summ, a) 21
Reduce >>> def summ(x, y): result = x + y print x, ' + ', y, ' = ', result return result >>> a = [1, 2, 3, 4, 5, 6] >>> reduce(summ, a) 1 + 2 = 3 3 + 3 = 6 6 + 4 = 10 10 + 5 = 15 15 + 6 = 21 21
Reduce >>> def summ(x, y): result = x + y print x, ' + ', y, ' = ', result return result >>> a = [1, 2, 3, 4, 5, 6] >>> reduce(summ, a) 1 + 2 = 3 3 + 3 = 6 6 + 4 = 10 10 + 5 = 15 15 + 6 = 21 21
Reduce >>> def summ(x, y): result = x + y print x, ' + ', y, ' = ', result return result >>> a = [1, 2, 3, 4, 5, 6] >>> reduce(summ, a) 1 + 2 = 3 3 + 3 = 6 6 + 4 = 10 10 + 5 = 15 15 + 6 = 21 21
Reduce >>> def summ(x, y): result = x + y print x, ' + ', y, ' = ', result return result >>> a = [1, 2, 3, 4, 5, 6] >>> reduce(summ, a) 1 + 2 = 3 3 + 3 = 6 6 + 4 = 10 10 + 5 = 15 15 + 6 = 21 21
Reduce >>> def summ(x, y): result = x + y print x, ' + ', y, ' = ', result return result >>> a = [1, 2, 3, 4, 5, 6] >>> reduce(summ, a) 1 + 2 = 3 3 + 3 = 6 6 + 4 = 10 10 + 5 = 15 15 + 6 = 21 21
Apply • Принимает в качестве параметров функцию и список • Применяет функцию к аргументам, взятым из списка
Apply apply(функция, список ее параметров)
Apply >>> def apply_sample(x, y, z): return x + y ** z >>> params = [1, 2, 3] >>> print apply(apply_sample, params) 9
lambda • lambda-функция – анонимная (безымянная) функция • позволяет создать функцию без присваивания ей имени • такая функция может быть сохранена в переменную • или использована через другие функции высшего порядка
lambda параметры : тело функции
lambda func = lambda x, y: x**2 + y**2 эквивалентно def func(x, y): return x**2 + y**2
lambda x, y: x**2 + y**2 аргументы тело функции Обратите внимание – return’а нет, но значение возвращается
lambda • Использование без сохранения в переменную >>> (lambda x: x+2) (5) 7
• Пример лямбда-функции для вычисления суммы трех чисел lambda x, y, z: x+y+z
lambda и apply >>> apply(lambda x, y: x ** y, (2, 6)) 64 >>> A=1, 2, [3, 4], [5, 6], 7 >>> B=2, 3 >>>apply(lambda x, y, z: x[y]. append(z), (A, 2, B)) >>> print A (1, 2, [3, 4, (2, 3)], [5, 6], 7)
lambda и map • map – применяет лямбду ко всем элементам списка по отдельности >>> list 1 = [7, 2, 3, 10, 12] >>> map(lambda x: x * -1, list 1) [-7, -2, -3, -10, -12]
lambda и filter >>> numbers = [10, 4, 2, -1, 6] >>> filter(lambda x: x < 5, numbers) # В результат попадают только те # элементы x, для которых x < 5 истинно [4, 2, -1]
lambda и map >>> list 1 = [7, 2, 3, 10, 12] >>> list 2 = [-1, 1, -5, 4, 6] >>> map(lambda x, y: x*y, list 1, list 2) [-7, 2, -15, 40, 72]
Генерация функций >>> def make_incrementor (n): return lambda x: x + n >>> f = make_incrementor(2) >>> g = make_incrementor(6) >>> print f(42), g(42) 44 48 >>> print make_incrementor(22)(33) 55
Модули
Подключаемые модули • Модули представляют собой коллекции готовых функций, которыми можно пользоваться
Модули 1) Подключение модуля целиком. import math #в области видимости доступен модуль с именем math x=math. sin(y) # функция вычисления синуса из модуля math
Подключение модуля • При подключении модуля целиком обращение к функции происходит через имя модуля • Модуль. Имя. Функции • math. sin(90)
Подключение модуля целиком >>> import math >>> decibel = math. log 10 (17. 0) >>> angle = 1. 5 >>> height = math. sin(angle)
константы >>> degrees = 45 >>> angle = degrees * math. pi / 180. 0 >>> math. sin(angle) 0. 707106781187
Модули 2) Подключение конкретной функции from random import randint #Импортируется функция randint your_variable = randint(1, 10) #Генерируется число from math import cos x=cos(y)
Модули Подключение всех функций модуля from string import *
Модули 1. Сервисы периода выполнения. Модули: sys, atexit, copy, traceback, math, cmath, random, time, calendar, datetime, sets, array, struct, itertools, locale, gettext. 2. Поддержка цикла разработки. Модули: pdb, hotshot, profile, unittest, pydoc. Пакеты docutils, distutils. 3. Взаимодействие с ОС (файлы, процессы). Модули: os, os. path, getopt, glob, popen 2, shutil, select, signal, stat, tempfile.
Модули 4. Обработка текстов. Модули: string, re, String. IO, codecs, difflib, mmap, sgmllib, htmllib, htmlentitydefs. Пакет xml. 5. Многопоточные вычисления. Модули: threading, thread, Queue. 6. Хранение данных. Архивация. Модули: pickle, shelve, anydbm, gzip, zlib, zipfile, bz 2, csv, tarfile. 7. Платформо-зависимые модули. Для UNIX: commands, pwd, grp, fcntl, resource, termios, readline, rlcompleter. Для Windows: msvcrt, _winreg, winsound.
Модули 8. Поддержка сети. Протоколы Интернет. Модули: cgi, Cookie, urllib, urlparse, httplib, smtplib, poplib, telnetlib, socket, asyncore. Примеры серверов: Socket. Server, Base. HTTPServer, xmlrpclib, asynchat. 9. Поддержка Internet. Форматы данных. Модули: quopri, uu, base 64, binhex, binascii, rfc 822, mimetools, Mime. Writer, multifile, mailbox. Пакет email. 10. Python о себе. Модули: parser, symbol, token, keyword, inspect, tokenize, pyclbr, py_compile, compileall, dis, compiler. 11. Графический интерфейс. Модуль Tkinter.