我正在尝试以功能方式编写 python 函数。问题是我不知道如何将 if 条件转换为功能样式。我有两个变量:A
和C
,我想检查以下条件:
def function():
if(A==0): return 0
elif(C!=0): return 0
elif(A > 4): return 0
else: someOtherFunction()
我查看了lambda shortcircuiting,但我无法让它工作。
我提前感谢您的帮助!
我正在尝试以功能方式编写 python 函数。问题是我不知道如何将 if 条件转换为功能样式。我有两个变量:A
和C
,我想检查以下条件:
def function():
if(A==0): return 0
elif(C!=0): return 0
elif(A > 4): return 0
else: someOtherFunction()
我查看了lambda shortcircuiting,但我无法让它工作。
我提前感谢您的帮助!
从您发布的链接:
FP 要么不鼓励要么完全禁止语句,而是使用表达式的评估
if
因此,您可以使用条件表达式来代替-statements :
def function():
return (0 if ((A == 0) or (C != 0) or (A > 4)) else
someOtherFunction())
或者,(如果有许多不同的值,则特别有用):
def function():
return (0 if A == 0 else
0 if C != 0 else
0 if A > 4 else
someOtherFunction())
顺便说一句,链接的文章提出
(<cond1> and func1()) or (<cond2> and func2()) or (func3())
作为一个短期课程等价于
if <cond1>: func1()
elif <cond2>: func2()
else: func3()
问题是它们不相等!<cond1>
当为 True 但func1()
为 Falsish(例如False
or0
或)时,布尔表达式无法返回正确的值None
。(或者类似地,什么时候<cond2>
是真但是func2
假的。)
(<cond1> and func1())
编写的目的是评估func1()
何时<cond1>
为真,但何时func1()
为假,(<cond1> and func1())
评估为False
,因此整个表达式被传递,Python 继续评估(<cond2> and func2())
而不是短路。
所以这里有一段有趣的历史。2005 年,
Raymond Hettingertype(z)==types.ComplexType and z.real or z
在when z = (0+4j)
because z.real
is Falsish中发现了一个类似的难以发现的错误。出于避免我们出现类似错误的愿望,使用不易出错的语法(条件表达式)的想法诞生了。
您当前的代码中没有任何非“功能样式”!谁说条件无论如何都不起作用?实际上,所有函数式语言都有某种条件运算符,例如cond
Lisp 中的特殊形式。
如果代码使用赋值运算符或以某种方式改变状态(例如,附加到列表),我会对代码提出异议,但事实上,问题中的函数已经处于“函数式” - 那里没有状态变化。
也许你的意思是这样的?
return A != 0 and C == 0 and A <= 4 and someOtherFunction()
False
如果是A == 0
orC != 0
或,以上将返回A > 4
,在所有其他情况下,它将返回 call 的值someOtherFunction()
。顺便说一句,False
可以假设评估为0
(例如,42 + False == 42
),因此从调用者的角度来看,问题中代码中的语义将被保留。
请注意,您将链接中的信息与上下文无关。绝对没有必要为此使用 a lambda
,本文仅说明如何绕过lambda
Python 中 s 的固有限制,即您不能在内部返回语句 (like if-elif-else
) - 只允许使用表达式,但您可以伪造他们用布尔运算符。无论如何,在正常函数的上下文中,使用条件。
尽管 Peter Norvig 是一个非常棒的人,但他的网站很难搜索。
我记得读过关于我可以在 Python 中做相当于 (test ? result : alternative) 的文章吗?在一次功能性 Python 演讲之前的一些研究期间,在他的网站上。
鉴于我的发现,我不会以某种方式左右你,但你仍然应该去阅读关于函数式三元条件运算符的部分。
def if_(test, result, alternative=None):
"If test is true, 'do' result, else alternative. 'Do' means call if callable."
if test:
if callable(result): result = result()
return result
else:
if callable(alternative): alternative = alternative()
return alternative
只需按原样使用它。
Python 没有内置的语法和库,因此可以轻松地对所有函数进行编程以直接返回单个表达式。无论如何,这不是功能样式最重要的部分,最重要的部分是确保您的函数保持引用完整性。基本上,这意味着无论何时为它们提供相同的输入值,它们都会返回相同的输出。
因此,当尝试在 Python 中进行函数式编程时,我并没有完全避免使用语句。我使用一个局部变量赋值块作为let ... in ...
来自 Haskell 的等价物。我使用 if/elif/else 链作为case
Haskell 中的表达式的等效项。并且通常有一些内置类型没有提供足够的接口来创建它们的新“修改”版本而不是就地更新它们,因此您必须使用显式复制操作来实现此类操作,然后使用突变新副本。
Python 允许您直接实现函数式设计。您可以轻松地将您的程序构建为一组显式传递状态且没有副作用的函数,因此您可以以与函数式编程语言非常相似的方式设计高级算法。从这个意义上说,几乎每种编程语言都支持函数式编程,如果您准备好忍受伪造一流函数所必需的样板文件。由于 Python具有一流的功能,因此您甚至不必忍受样板文件。
但这就是 Python 在支持函数式编程方面的表现。它并不真正支持将函数实现为单个引用透明的表达式。但这并不重要。在不强制或不跟踪纯度的语言中,您可以获得函数式编程的几乎所有好处,您只需将程序设计为一堆引用透明的函数,然后如何实现这些函数实际上并不重要只要接口保持引用透明。