Работаем с функциями в python

Содержание:

Создание Shadow DOM

Примеры получения/ввода данных из консоли/клавиатуры.

  • ;
  • ;
  • .

Общие примеры использования функции .

>>> x = input('Enter your name:')
# Enter your name:Anton
>>> print('Hello, ', x)
# Hello,  Anton

# Можно и без строки подсказки
>>> print('Введите число:')
# Введите число:
>>> x = input()
# 10

# Не забываем что функция 
# возвращает строку
>>> x
# '10'

Проверка и преобразование типов при вводе данных с клавиатура.

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

# test.py 

def str_to_num(line):
    """функция конвертирует строку в число"""
    line = line.strip()
    # если в строке только цифры
    if line.isdigit():
        return int(line) 
    # если строка содержит точку или запятую
    elif '.' in line or ',' in line
        # если из строки убрать точку или запятую
        # и при этом в строке останутся только цифры
        if any(line.replace(x, '').isdigit() for x in '.', ',']):
            return float(line.replace(',', '.'))
    else
        # ошибка
        print('Это не число!\n')
        return None

print('\nДля выхода из программы введите Ctrl+C')
print('Для окончания ввода цифр нажмите Enter\n')

nums = []
while True
    inpt = input('Ожидается ввод числа или Enter:')
    if inpt == ''
        # Закончить ввод чисел
        break
    n = str_to_num(inpt)
    if n is not None
        nums.append(n)

if nums
    if len(nums) == 1
        print('Вы ввели одну цифру: ', nums])
    else
        print('\nВыберите действие:')
        print('  сложить цифры введите 1;')
        print('  умножить цифры введите 2.\n')

        rez = None
        while True
            inpt = input('Введите 1 или 2:')
            inpt = inpt.strip()
            if inpt == '1'
                rez = sum(nums)
                print('Сумма введенных чисел:', rez)
            elif inpt == '2'
                rez = 1
                for i in nums
                    rez *= i
                print('Произведение введенных чисел:', rez)
            else
                print('Неправильное действие.\n')
            
            if rez is not None
                break
else
    print('Вы ничего не ввели.')

Вывод программы:

$ python3 test.py 

Для выхода из программы введите Ctrl+C
Для окончания ввода цифр нажмите Enter

Ожидается ввод числа или Enter:10
Ожидается ввод числа или Enter:13.9
Ожидается ввод числа или Enter:9,9
Ожидается ввод числа или Enter:

Выберите действие:
  сложить цифры введите 1;
  умножить цифры введите 2.

Введите 1 или 2:2
Произведение введенных чисел: 1376.1000000000001

Эмуляция терминала с использованием функцией .

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

# test.py
import sys, traceback

def run_user_code(envdir):
    source = input(">>> ")
    try
        # Выполнение введенного кода с клавиатуры
        exec(source, envdir)
    except Exception
        print("Exception in user code:")
        print("-"*60)
        traceback.print_exc(file=sys.stdout)
        print("-"*60)

# словарь для хранения введенных переменных
envdir = {}

while True
    run_user_code(envdir)

Запускаем эмуляцию интерпретатора Python.

Синтаксис

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

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

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

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

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

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

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

Для чего используется *args в Python?

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

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

lets_multiply.py

Python

def multiply(x, y):
print (x * y)

1
2

defmultiply(x,y)

print(x*y)

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

lets_multiply.py

Python

def multiply(x, y):
print (x * y)

multiply(5, 4)

1
2
3

defmultiply(x,y)

print(x*y)

Сейчас мы можем запустить код:

Shell

python lets_multiply.py

1 python lets_multiply.py

Мы получим следующий результат, показывающий, что целые числа 5 и 4 были умножены функцией :

Shell

20

1 20

Что, если позже мы решим умножить три числа, а не два? Если мы попытаемся добавить к функции дополнительное число, как показано ниже, мы получим .

lets_multiply.py

Python

def multiply(x, y):
print (x * y)

multiply(5, 4, 3)

1
2
3
4

defmultiply(x,y)

print(x*y)

multiply(5,4,3)

Вывод:

Shell

TypeError: multiply() takes 2 positional arguments but 3 were given

1 TypeErrormultiply()takes2positional arguments but3were given

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

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

lets_multiply.py

Python

def multiply(*args):
z = 1
for num in args:
z *= num
print(z)

multiply(4, 5)
multiply(10, 9)
multiply(2, 3, 4)
multiply(3, 5, 10, 6)

1
2
3
4
5
6
7
8
9
10

defmultiply(*args)

z=1

fornum inargs

z*=num

print(z)

multiply(4,5)

multiply(10,9)

multiply(2,3,4)

multiply(3,5,10,6)

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

Shell

20
90
24
900

1
2
3
4

20
90
24
900

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

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

Функтор

Функтор — это не функция, а объект класса, в котором определён метод с именем
. При этом, для экземпляра такого объекта может
применяться вызов, точно так же, как это происходит для функций. В листинге 7 (файл part.py
из архива python_functional.tgz в разделе «Материалы для скачивания») демонстрируется
использование замыкания, частичного определения функции и функтора, приводящих к получению одного и
того же результата.

Листинг 7. Сравнение замыкания, частичного определения и функтора
# -*- coding: utf-8 -*-

def multiplier( n ):    # замыкания - closure
    def mul( k ):
        return n * k
    return mul

mul3 = multiplier( 3 )

from functools import partial
def mulPart( a, b ):    # частичное применение функции
    return a * b

par3 = partial( mulPart, 3 )

class mulFunctor:       # эквивалентный функтор
    def __init__( self, val1 ):
        self.val1 = val1
    def __call__( self, val2 ):
        return self.val1 * val2

fun3 = mulFunctor( 3 )

print( '{} . {} . {}'.format( mul3( 5 ), par3( 5 ), fun3( 5 ) ) )

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

$ python part.py
15 . 15 . 15

Способы извлечения корня

В языке программирования Python 3 существует три способа извлечения корней:

  • Использование функции sqrt из стандартной математической библиотеки math.
  • Операция возведения в степень **
  • Применение функции pow(x, n)

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

from math import sqrt
x = sqrt(4)
print(x)

2.0

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

from math import hypot
x = hypot(4,3)
print(x)

5.0

Еще одним, чуть более универсальным методом, будет использование возведения в степень. Известно, что для того, чтобы взять корень n из числа, необходимо возвести его в степень 1/n. Соответственно, извлечение квадратного корня из числа 4 будет выглядеть так:

n = 2
x = 4**(1./n)
print(x)

2.0

Обратите внимание, что в Python 2 необходимо ставить точку после единицы, иначе произойдет целочисленное деление, и 1/n == 0, а не нужной нам дроби. В Python 3 можно не ставить точку.. Последний метод использует функцию pow(value, n)

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

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

x = pow(4, 0.5)
print(x)

2.0

Какой метод быстрее?

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

from time import monotonic
from math import sqrt
iterations = 1000000
start = monotonic()
for a in range(iterations):
    x = sqrt(4)
print("sqrt time: {:>.3f}".format(monotonic() - start) + " seconds")
start = monotonic()
for a in range(iterations):
    x = 4 ** 0.5
print("** time: {:>.3f}".format(monotonic() - start) + " seconds")
start = monotonic()
for a in range(iterations):
    x = pow(4, 0.5)
print("pow time: {:>.3f}".format(monotonic() - start) + " seconds")

sqrt time: 0.266 seconds
** time: 0.109 seconds
pow time: 0.453 seconds

Как видно, самое быстрое решение – использовать **. На втором месте метод sqrt, а pow – самый медленный. Правда, метод sqrt наиболее нагляден при вычислении в Python квадратных корней.

Таким образом, если критична скорость, то используем **. Если скорость не критична, а важна читаемость кода, то следует использовать sqrt.

Подготавливаем стены

Ключевые аргументы

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

Python

def keyword_function(a=1, b=2):
return a+b

print( keyword_function(b=4, a=5) ) # 9

1
2
3
4

defkeyword_function(a=1,b=2)

returna+b

print(keyword_function(b=4,a=5))# 9

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

Python

keyword_function() # 3

1 keyword_function()# 3

Функция вернулась к нам с числом 3. Почему? Причина заключается в том, что а и b по умолчанию имеют значение 1 и 2 соответственно. Теперь попробуем создать функцию, которая имеет обычный аргумент, и несколько ключевых аргументов:

Python

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

mixed_function(b=4, c=5)

Traceback (most recent call last):
File «<string>», line 1, in <fragment>
TypeError: mixed_function() takes at least 1 argument (2 given)

1
2
3
4
5
6
7
8

defmixed_function(a,b=2,c=3)

returna+b+c

mixed_function(b=4,c=5)

Traceback(most recent call last)

File»<string>»,line1,in<fragment>

TypeErrormixed_function()takes at least1argument(2given)

Python

print( mixed_function(1, b=4, c=5) ) # 10

print( mixed_function(1) ) # 6

1
2
3

print(mixed_function(1,b=4,c=5))# 10

print(mixed_function(1))# 6

Выше мы описали три возможных случая. Проанализируем каждый из них. В первом примере мы попробовали вызвать функцию, используя только ключевые аргументы. Это дало нам только ошибку. Traceback указывает на то, что наша функция принимает, по крайней мере, один аргумент, но в примере было указано два аргумента. Что же произошло? Дело в том, что первый аргумент необходим, потому что он ни на что не указывает, так что, когда мы вызываем функцию только с ключевыми аргументами, это вызывает ошибку. Во втором примере мы вызвали смешанную функцию, с тремя значениями, два из которых имеют название. Это работает, и выдает нам ожидаемый результат: 1+4+5=10. Третий пример показывает, что происходит, если мы вызываем функцию, указывая только на одно значение, которое не рассматривается как значение по умолчанию. Это работает, если мы берем 1, и суммируем её к двум значениям по умолчанию: 2 и 3, чтобы получить результат 6! Удивительно, не так ли?

Функция как объект в Python

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

>>> # исходный список
>>> a = 1, 2, 3, 4, 5
>>> # функция, которая возводит в квадрат переданное ей число 
>>> sq = lambda x x**2
>>> # проверка работы функции в Python
>>> print(sq(5))
25

>>> # получение списка квадратов
>>> b = list(map(sq, a))
>>> print(b)
1, 4, 9, 16, 25

В нашем примере мы передали функции map в виде первого аргумента функцию sq. Последняя будет по очереди применяться ко всем элементам нашего списка a.

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

class DemoCall():
def __call__(self):
return "Hello!"

Объект такого класса в Python мы сможем вызывать как функцию:

>>> hello = DemoCall()
>>> hello()
'Hello!'

Условное выражение (или «Тернарный оператор»)

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

  • Порядок аргументов отличается от многих других языков (таких как C, Ruby, Java и т. Д.), Что может привести к ошибкам, когда люди, незнакомые с «удивительным» поведением Python, используют его (они могут изменить порядок).
  • Некоторые считают его «громоздким», поскольку он идет вразрез с нормальным потоком мысли (сначала думая о состоянии, а затем о последствиях).

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

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

Они также обеспечивают способ включения условных в функции лямбды .

Встроенные типы

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

Optional

Если вы пометите переменную типом и попытаетесь присвоить ей , будет ошибка:

Для таких случаев предусмотрена в модуле typing аннотация с указанием конкретного типа

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

Any

Иногда вы не хотите ограничивать возможные типы переменной

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

На следующий код mypy не будет ругаться:

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

Union

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

Кстати, аннотация эквивалентна , хотя такая запись и не рекомендуется.

Коллекции

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

Списки

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

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

Кроме списка аналогичные аннотации есть для множеств: и .

Кортежи

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

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

Аннотация без указания типов элементов работает аналогично

Словари

Для словарей используется . Отдельно аннотируется тип ключа и тип значений:

Аналогично используются и

Результат выполнения функции

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

Если функция ничего не возвращает (например, как ), её результат всегда равен . Для аннотации так же используем .

Корректными вариантами завершения такой функции будут: явный возврат , возврат без указания значения и завершение без вызова .

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

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

print

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

print(1)
print(1, 2)
print(1, 2, 3)

И так далее,
число аргументов может быть произвольным. Соответственно все эти значения в
строчку будут выведены в консоли. Причем, значения разделяются между собой
пробелом. Это разделитель, который используется по умолчанию. Если нужно
изменить значение этого разделителя, то для этого используется специальный
именованный аргумент sep:

print(1, 2, 3, sep=",")
print(1, 2, 3, sep="-")
print(1, 2, 3, sep="***")

то есть, здесь можно прописывать самые разные строки-разделители.

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

print(1, 2, 3, sep=",", end=':')
print(1, 2, 3, sep="-", end='--end--\n')
print(1, 2, 3, sep="***")

Смотрите, теперь
у нас после первой строчки нет перевода строки, а поставлено двоеточие с
пробелом, которые мы указали в аргументе end. После второго
вывода в конце была добавлена строчка и указан символ ‘\n’ перевода
строки.

В качестве
примера все это можно использовать для более гибкого вывода значений с помощью print:

name = "Федор"
print("Имя", name, sep=":")

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

name = "Федор"; age = 18
print("Имя %s, возраст %d"%(name, age))

В результате,
вместо спецификатора %s будет подставлена первая переменная,
указанная в скобках, в виде строки, а вместо %d – вторая
переменная age в виде целого
числа. То есть, для каждого типа данных существует свой спецификатор. Наиболее
употребительные, следующие:

  • %d, %i, %u – для вывода целочисленных
    значений;

  • %f – для вывода
    вещественных значений;

  • %s
    – для
    вывода строк;

  • %%
    — для
    вывода символа %

Вот основные
возможности функций input и print в Python.

Видео по теме

Python 3 #1: установка и запуск интерпретатора языка

Python 3 #2: переменные, оператор присваивания, типы данных

Python 3 #3: функции input и print ввода/вывода

Python 3 #4: арифметические операторы: сложение, вычитание, умножение, деление, степень

Python 3 #5: условный оператор if, составные условия с and, or, not

Python 3 #6: операторы циклов while и for, операторы break и continue

Python 3 #7: строки — сравнения, срезы строк, базовые функции str, len, ord, in

Python 3 #8: методы строк — upper, split, join, find, strip, isalpha, isdigit и другие

Python 3 #9: списки list и функции len, min, max, sum, sorted

Python 3 #10: списки — срезы и методы: append, insert, pop, sort, index, count, reverse, clear

Python 3 #11: списки — инструмент list comprehensions, сортировка методом выбора

Python 3 #12: словарь, методы словарей: len, clear, get, setdefault, pop

Python 3 #13: кортежи (tuple) и операции с ними: len, del, count, index

Python 3 #14: функции (def) — объявление и вызов

Python 3 #15: делаем «Сапер», проектирование программ «сверху-вниз»

Python 3 #16: рекурсивные и лямбда-функции, функции с произвольным числом аргументов

Python 3 #17: алгоритм Евклида, принцип тестирования программ

Python 3 #18: области видимости переменных — global, nonlocal

Python 3 #19: множества (set) и операции над ними: вычитание, пересечение, объединение, сравнение

Python 3 #20: итераторы, выражения-генераторы, функции-генераторы, оператор yield

Python 3 #21: функции map, filter, zip

Python 3 #22: сортировка sort() и sorted(), сортировка по ключам

Python 3 #23: обработка исключений: try, except, finally, else

Python 3 #24: файлы — чтение и запись: open, read, write, seek, readline, dump, load, pickle

Python 3 #25: форматирование строк: метод format и F-строки

Python 3 #26: создание и импорт модулей — import, from, as, dir, reload

Python 3 #27: пакеты (package) — создание, импорт, установка (менеджер pip)

Python 3 #28: декораторы функций и замыкания

Python 3 #29: установка и порядок работы в PyCharm

Python 3 #30: функция enumerate, примеры использования

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

  • ;
  • ;
  • ;
  • ;
  • ;
  • .
# использование позиционных аргументов
>>> 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)
# 

Функции как объекты

Создавая объект функции оператором , как было
показано в листинге 1, можно привязать созданный функциональный объект к имени
в точности так же, как можно было бы привязать к этому имени
число или строку .
Этот пример подтверждает статус функций как объектов первого класса в Python. Функция в Python — это всего
лишь ещё одно значение, с которым можно что-то сделать.

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

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

Комбинируя эти три функции, можно реализовать неожиданно широкий диапазон операций потока
управления, не прибегая к императивным утверждениям, а используя лишь выражения в функциональном стиле,
как показано в листинге 2 (файл funcH.py из архива python_functional.tgz
в разделе «Материалы для скачивания»):

Листинг 2. Функции высших порядков Python
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
def input_arg():
    global arg
    arg = ( lambda: ( len( sys.argv ) > 1 and int( sys.argv ) ) or \
                      int( input( "число?: " ) ) )()
    return arg

print( 'аргумент = {}'.format( input_arg() ) )
print( list( map( lambda x: x + 1, range( arg ) ) ) )
print( list( filter( lambda x: x > 4, range( arg ) ) ) )

import functools
print( '{}! = {}'.format( arg, functools.reduce( lambda x, y: x * y,
                                                 range( 1, arg ) ) ) )

Примечание. Этот код несколько усложнён по сравнению с предыдущим примером из-за
следующих аспектов, связанных с совместимостью Python версий 2 и 3:

  • Функция , объявленная как встроенная в Python 2, в Python 3
    была вынесена в модуль и её прямой вызов по имени
    вызовет исключение , поэтому для корректной работы
    вызов должен быть оформлен как в примере или включать строку:
  • Функции и
    в Python 3 возвращают не список (что уже показывалось при обсуждении различий версий), а объекты-итераторы
    вида:

    <map object at 0xb7462bec>
    <filter object at 0xb75421ac>

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

Поэтому такой код сможет работать в обеих версиях Python:

$ python3 funcH.py 7
аргумент = 7


7! = 720

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

Python Tutorial

Python HOMEPython IntroPython Get StartedPython SyntaxPython CommentsPython Variables
Python Variables
Variable Names
Assign Multiple Values
Output Variables
Global Variables
Variable Exercises

Python Data TypesPython NumbersPython CastingPython Strings
Python Strings
Slicing Strings
Modify Strings
Concatenate Strings
Format Strings
Escape Characters
String Methods
String Exercises

Python BooleansPython OperatorsPython Lists
Python Lists
Access List Items
Change List Items
Add List Items
Remove List Items
Loop Lists
List Comprehension
Sort Lists
Copy Lists
Join Lists
List Methods
List Exercises

Python Tuples
Python Tuples
Access Tuples
Update Tuples
Unpack Tuples
Loop Tuples
Join Tuples
Tuple Methods
Tuple Exercises

Python Sets
Python Sets
Access Set Items
Add Set Items
Remove Set Items
Loop Sets
Join Sets
Set Methods
Set Exercises

Python Dictionaries
Python Dictionaries
Access Items
Change Items
Add Items
Remove Items
Loop Dictionaries
Copy Dictionaries
Nested Dictionaries
Dictionary Methods
Dictionary Exercise

Python If…ElsePython While LoopsPython For LoopsPython FunctionsPython LambdaPython ArraysPython Classes/ObjectsPython InheritancePython IteratorsPython ScopePython ModulesPython DatesPython MathPython JSONPython RegExPython PIPPython Try…ExceptPython User InputPython String Formatting

Замыкание

Одно из интересных понятий функционального программирования — это замыкания
(closure). Эта идея оказалась настолько заманчивой для многих разработчиков, что была реализована даже в
некоторых нефункциональных языках программирования (Perl). Девид Мертц приводит следующее
определение замыкания: «Замыкание — это процедура вместе с привязанной к ней совокупностью данных» (в
противовес объектам в объектном программировании, как: «данные вместе с привязанным к ним совокупностью
процедур» ).

Смысл замыкания состоит в том, что определение функции «замораживает» окружающий её контекст на
момент определения. Это может делаться различными способами, например, за счёт
параметризации создания функции, как показано в листинге 5 (файл clos1.py в архиве
python_functional.tgz в разделе «Материалы для скачивания»):

Листинг 5. Создание замыкания
# -*- coding: utf-8 -*-

def multiplier( n ):    # multiplier возвращает функцию умножения на n
    def mul( k ):
        return n * k
    return mul

mul3 = multiplier( 3 )  # mul3 - функция, умножающая на 3
print( mul3( 3 ), mul3( 5 ) )

Вот как срабатывает такая динамически определённая функция:

$ python clos1.py
(9, 15)
$ python3 clos1.py
9 15

Другой способ создания замыкания — это использование значения параметра по умолчанию в точке
определения функции, как показано в листинге 6 (файл clos3.py из архива python_functional.tgz
в разделе «Материалы для скачивания»):

Листинг 6. Другой способ создания замыкания
n = 3
def mult( k, mul = n ):
    return mul * k

n = 7
print( mult( 3 ) )
n = 13
print( mult( 5 ) )

n = 10
mult = lambda k, mul=n: mul * k
print( mult( 3 ) )

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

$ python clos3.py
9
15
30
Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector