Lambda в python

Я пересматриваю некоторые схемы excercises в python (если это имеет смысл), чтобы узнать, что питон может делать с точки зрения FP. Моя проблема касается лямбда в python: Могу ли я определить общую функцию в python с оператором в качестве одного из аргументов?

Подумайте об этом:

def f (op,x,y):
    #return some lambda function that combines x and y in the appropriate way
    #i.e if op is +, then return x+y, if op is -, then return x-y etc

#Edit : added usage
#this should be called like this:
f(+, 1,2) #should return 3

Я знаю, что это возможно в схеме, но есть ли что-то эквивалентное в python? У меня сложилось впечатление, что лямбда в python - это всего лишь более короткий способ определения метода, и я не нашел способа определить общую функцию объединения в python.

Ответы

Ответ 1

Я вижу некоторые моменты в вашем вопросе, пропуская их в порядке:

1. Могу ли я передать функцию как параметр кому-то?

Да:

def f(op, x, y):
    return op(x, y)

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

f(add, 10, 7) #gives 17

2. Как насчет операторов?

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

import operator

operator.add(1, 2)
(lambda x,y : x+y)(1, 2)

Операторы, не являющиеся реальными функциями, в большинстве случаев немного печальны, но по крайней мере Python дает нам скованные сравнения, такие как 10 <= x < 100 в обмене...

3. Так в чем же разница между Python и Scheme?

В общем смысле функции в Python столь же сильны, как и функции на Схеме, однако есть некоторые вещи, которые следует отметить:

Ключевое слово lambda ограничено

У вас может быть только одно выражение как тело функции

f = lambda x, y: x + y

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

Есть замыкания

def make_printer(msg):
    def printer():
        print msg
    return printer

printer('a message')()

Но мутирующие переменные в них - это боль

Это не работает. Он пытается связать новый n для внутренней функции, а не использовать внешний

def make_counter(n):
    def inc():
        n = n + 1
        return n
    return inc

новое 3.x нелокальное ключевое слово

def make_counter(n):
    def inc():
        nonlocal n
        n = n + 1
        return n
    return inc

обходной путь w/изменяемые объекты

def make_counter(n):
    nw = [n]
    def inc():
       nw[0] = nw[0] + 1
       return nw[0]
    return inc

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

class Counter:
    def __init__(self, n):
        self.n = n
    def __call__(self):
        self.n += 1
        return self.n

Ответ 2

Операторы на самом деле не функционируют в python, больше похоже на методы - x + y меньше для x.__add__(y) или y.__radd__(x). Вы можете использовать функции в модуле operator, чтобы эмулировать поведение, которое вы хотите.

Ответ 3

Я думаю, что ваш лучший выбор - сделать функцию, которая выполняет оператор, и передать это:

def f(op, x, y):
    return op(x, y)

f(lambda x, y: x + y, 1, 2)

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

f = lambda x, y: x + y

f(1, 2)

Ответ 4

Синтаксически нельзя передать оператор в python. Например. f(+) - синтаксическая ошибка. Однако, если вы считаете, что op является какой-либо функцией, вы можете использовать def или лямбда:

def f(op, x, y):
  def op_func():
    return op(x, y)

  return op_func

or

def f(op, x, y):
  op_func = lambda: op(x, y)

  return op_func

В вашем случае вы хотите оценить функцию:

def f(op, x, y):
    return op(x, y)

Помните, что интерпретатор Python интерпретируется, поэтому даже оценки def вычисляются во время выполнения.

[Если по какой-то причине вам нужно, вы можете обращаться к встроенным операторам как к функциям с помощью операторского модуля: http://docs.python.org/library/operator.html]

Ответ 5

Проверьте модуль operator. Все операторы python доступны там в виде функций. Пример:

import operator    
operate = lambda op, x, y: op(x, y)
operate(operator.add, 1, 2)