2016-09-21 2 views
0

Я просто переключился на Python из Matlab, и я хочу использовать функцию лямбда для сопоставления функции f1(x,y) с несколькими аргументами для одной функции аргумента f2(x) для оптимизации. Я хочу, чтобы, когда я карта функции f2(x) <- f1(x,y=y1) тогда y будет оставаться постоянным, независимо от того, каких y1 изменений в Matlab это верно по умолчанию, но если я пытаюсь в Python, она постоянно меняется, как в следующих примерахлямбда-функция другой функции, но сила фиксированного аргумента

>>> def f1(x,y): 
>>> return (x+y) 
>>> y1 = 2 
>>> f2 = lambda x: f1(x,y1) 
>>> f2(1) 
3 

I ожидать f2(1) остается 3, даже если я изменить y1, однако, если я изменю y1, вся f1(1) также изменяется следующим образом

>>> y1 = 5 
>>> f2(1) 
6 

Интересно, есть ли способ, что, когда я Децл находятся в положении f2 = lambda x: f1(x,y1), после этого f1 в это время принимает значение y1 и фиксирует его на f2. Причина этого в том, что я хочу динамически создавать разные функции для разных сценариев, а затем суммировать их все. Я все еще новичок в Python, пожалуйста, помогите, очень ценю.

ответ

2

Try:

f2 = lambda x, y=y1: f1(x,y) 

Ваш вопрос связан с how closures work in Python

Ваш вариант лямбда-функции будет использовать текущую версию y1. Вам нужно, чтобы захватить значение y1 на линии, где вы определили функцию лямбда. Для этого вы можете определить его как значение по умолчанию для параметра (часть y=y1).

+0

теперь он работает, как я хочу, спасибо за совет , Я чувствую, что это своего рода трюк, поскольку 'f2' на самом деле все еще имеет два аргумента, но он также принимает один аргумент, следовательно, работает для моего случая. –

1

Как уже указывалось, ваша проблема сводится к тому, как работают замыкания. Тем не менее, вы действительно не должны использовать лямбда для этого - lambdas предназначены для анонимных функций. Сделать функцию высшего порядка с def заявления вместо:

>>> def f1(x,y): 
... return x + y 
... 
>>> def f1_factory(y): 
... def f1_y(x): 
...  return f1(x,y) 
... return f1_y 
... 
>>> f1_factory(6)(4) 
10 
>>> f1_factory(5)(4) 
9 

Это также позволяет избежать проблемы, с которой вы столкнулись:

>>> y = 3 
>>> newfunc = f1_factory(y) 
>>> newfunc(1) 
4 
>>> y = 20 
>>> newfunc(1) 
4 
>>> 

От PEP8:

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

Да:

Защиту е (х): возвращение 2 * х

No:

е = лямбда х: 2 * х

Первая форма означает, что имя результирующий функциональный объект является специально «f» вместо общего <lambda>. Это более полезно для отслеживания и представления строк в общем.Использование оператора присваивания устраняет единственную выгоду лямбда-выражение может предложить более явное заявление четкости (т.е. то, что он может быть встроен внутри большего выражения)

+0

Я всегда использую функцию @ в Matlab, я думал, что функция лямбда в Python - это то же самое. Я буду иметь это в виду для будущего кодирования, спасибо за советы –

+0

@JoseVu Это скорее вопрос стиля. Обе эти функции являются анонимными. Но стиль в Python заключается в том, что если ваша анонимная функция не будет, ну, анонимная, то просто используйте инструкцию определения полного функционала. –

Смежные вопросы