在 python 中创建接受表达式作为输入的函数
Create a function that accepts an expression as an input in python
我正忙于编写一些关于二分法的代码。当然,编写脚本并 运行 它很容易。但是,当我想定义一个将采用 x**2 等表达式作为输入的函数时,技巧就出现了。不过,我已经把一些东西拼凑在一起了。它有点完成工作,但在我的第一个 if 语句中它抱怨无法将一个函数乘以一个函数。我将如何解决这个问题?
在提问之前,我确实尝试过在这个问题上做功课,但不幸的是找不到解决方案。我只是想知道如何做到这一点。
from sympy.abc import x
def bisect(f, a, b):
f = lambda x: f
f_a, f_b = f(a), f(b)
tol = 1e-4
count = 0
print '\t'.join( ['Step' , 'a', 'b', 'c', 'f(c) ' , '(b-a)/2)'])
while (b-a)/float(2) > tol:
c = (a+b)/2
f_c = f(c)
print '\t'.join( [str(count) , str(a) , str(b) , str(c), str((b-a)/float(2) )])
if f_a*f_c < 0:
b = c
f_b = f_c
else:
a = c
f_a = f_c
count = count + 1
这是你需要知道的吗?
>>> def demo(func):
... for i in range(5):
... print func( float(i))
...
>>> demo( lambda x: x**2 + 2*x - 5 )
-5.0
-2.0
3.0
10.0
19.0
您还可以传入使用 def
创建的函数以及使用 lambda
定义的 one-liner。以上同
def foo(x):
return x**2 + 2*x - 5
demo( foo)
您可能想知道的另一件事是
definition = "x**2 + 2*x - 5" # or read it from the user as text input
demo( eval( "lambda x: " + definition))
有效...
强制性警告、"eval is evil"、接受用户Python代码并执行一般视为安全no-no-NO!但是,如果此代码是由正在尝试绘制数学形式的同一用户 运行 编写的,则不会有太大的危害。他不能做任何比他在命令行用 python
能做的更糟糕的事情。如果你在 web-server 之类的地方做这样的事情,我会担心你的就业和未来的前景!
假设您已经使用 sympy
:
为函数 f
创建了一个表达式
f = x**2-0.1
如果您更改 lambda
定义,您的 bisect
函数将起作用:
def bisect(fexpr, a, b):
f = lambda xval: fexpr.subs(x,xval)
f_a, f_b = f(a), f(b)
...
我正忙于编写一些关于二分法的代码。当然,编写脚本并 运行 它很容易。但是,当我想定义一个将采用 x**2 等表达式作为输入的函数时,技巧就出现了。不过,我已经把一些东西拼凑在一起了。它有点完成工作,但在我的第一个 if 语句中它抱怨无法将一个函数乘以一个函数。我将如何解决这个问题? 在提问之前,我确实尝试过在这个问题上做功课,但不幸的是找不到解决方案。我只是想知道如何做到这一点。
from sympy.abc import x
def bisect(f, a, b):
f = lambda x: f
f_a, f_b = f(a), f(b)
tol = 1e-4
count = 0
print '\t'.join( ['Step' , 'a', 'b', 'c', 'f(c) ' , '(b-a)/2)'])
while (b-a)/float(2) > tol:
c = (a+b)/2
f_c = f(c)
print '\t'.join( [str(count) , str(a) , str(b) , str(c), str((b-a)/float(2) )])
if f_a*f_c < 0:
b = c
f_b = f_c
else:
a = c
f_a = f_c
count = count + 1
这是你需要知道的吗?
>>> def demo(func):
... for i in range(5):
... print func( float(i))
...
>>> demo( lambda x: x**2 + 2*x - 5 )
-5.0
-2.0
3.0
10.0
19.0
您还可以传入使用 def
创建的函数以及使用 lambda
定义的 one-liner。以上同
def foo(x):
return x**2 + 2*x - 5
demo( foo)
您可能想知道的另一件事是
definition = "x**2 + 2*x - 5" # or read it from the user as text input
demo( eval( "lambda x: " + definition))
有效...
强制性警告、"eval is evil"、接受用户Python代码并执行一般视为安全no-no-NO!但是,如果此代码是由正在尝试绘制数学形式的同一用户 运行 编写的,则不会有太大的危害。他不能做任何比他在命令行用 python
能做的更糟糕的事情。如果你在 web-server 之类的地方做这样的事情,我会担心你的就业和未来的前景!
假设您已经使用 sympy
:
f
创建了一个表达式
f = x**2-0.1
如果您更改 lambda
定义,您的 bisect
函数将起作用:
def bisect(fexpr, a, b):
f = lambda xval: fexpr.subs(x,xval)
f_a, f_b = f(a), f(b)
...