лямбда в питоне - PullRequest
       1

лямбда в питоне

16 голосов
/ 02 ноября 2011

Я возвращаюсь к некоторым схемным упражнениям в python (если это имеет смысл), чтобы узнать, что python может делать с точки зрения FP. Моя проблема касается лямбды в питоне: Могу ли я определить общую функцию в 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.

Ответы [ 5 ]

14 голосов
/ 02 ноября 2011

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

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 столь же мощны, как и функции в Scheme, однако есть некоторые вещи, на которые следует обратить внимание:

Ключевое слово 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

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

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

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

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
8 голосов
/ 02 ноября 2011

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

2 голосов
/ 02 ноября 2011

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

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)
1 голос
/ 02 ноября 2011

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

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]

0 голосов
/ 02 ноября 2011

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

import operator    
operate = lambda op, x, y: op(x, y)
operate(operator.add, 1, 2)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...