我开始通过编写ODE求解器来学习Python。我想透明地处理一个或多个变量的输入函数。这里是我的欧拉方法的一个步骤代码:将数值类型透明地处理为单值序列(反之亦然)
def euler(h, t, y, f):
return (y + h*f for y,f in zip(y,f(t,y)))
现在我定义了两个功能,f1
和f2
这样的:
def f1(t,y):
return -2*t*y
def f2(t,y):
x, y = y #is rebinding usually ok, or confusing?
return (x - t*y, y + x/t)
当我测试他们,这就是(明显)发生
>>> list(euler(0.01, 1, (1,2), f2))
[0.99, 2.03]
>>> list(euler(0.01, 1, 1, f1))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in euler
TypeError: zip argument #1 must support iteration
我希望求解器能够透明地处理,如果给定的函数适用于一个或多个变量,但还没有找到一个很酷的方法来做到这一点。某种程度上,我发现
import operator as op
def euler(h, t, y, f):
if op.isNumberType(y):
return (y + h*f(t,y),)
return (y + h*f for y,f in zip(y,f(t,y)))
但现在我通过一个浮动并返回一个迭代,所以list(euler(...))
可以suceed。但是,我不能拨打电话,例如f(t,euler(...))
。
有没有办法将单例序列作为基元类型处理,或者将原始单元作为单例序列处理而没有无限检查?通过“无尽检查”我的意思是,必须在几个地方检查,而不是遍及我的代码。或者我应该吸吮它,并使f(t,y)
期望一个序列,而不是数字?
感谢您的任何帮助,并欢迎我的编码提示!
你的答案与我的不同之处如何? – Abhijit
在f1之后有一个逗号。 – HYRY
我喜欢@HYRY的最好,因为它证明了它们之间的相似之处。谢谢大家的答案。 –