要制作Lambda,您需要一些未评估的内容。 d[1]
马上评估字典的价值(x
)。
据我所知,SymPy中已经没有这样的对象了。 IndexedBase将是最接近的,但它应该索引到有序的容器中,并且无论如何都不能真正替代确切的容器。
这是一个简单的事情,似乎工作。我不确定UnevaluatedDict
中的评估逻辑是否正确。此外,我没有更改UnevaluatedDict
上的打印机,因此打印为d[1]
而不是UnevaluatedDict(d, 1)
。请注意,我必须使用一些技巧才能让SymPy和Python不会认为UnevaluatedDictBase
是可迭代的(否则事情会尝试执行for i in d
并陷入无限循环)。
这些东西可能还有更好的名字(真的IndexedBase
应该像这样工作)。
from sympy.core.compatibility import NotIterable
class UnevaluatedDictBase(Symbol, NotIterable):
def __getitem__(self, item):
return UnevaluatedDict(self, item)
def __iter__(self):
raise TypeError("UnevaluatedDictBase is not iterable")
class UnevaluatedDict(Expr):
def __new__(cls, d, item):
if hasattr(d, '__getitem__') and not isinstance(d, UnevaluatedDictBase):
return d[item]
return super(UnevaluatedDict, cls).__new__(cls, d, item)
这就像
In [35]: d = UnevaluatedDictBase('d')
In [36]: d[1]
Out[36]: UnevaluatedDict(d, 1)
In [37]: d[1].subs(d, {1: x})
Out[37]: x
In [61]: Lambda(d, d[1] + d[2])
Out[61]: d ↦ UnevaluatedDict(d, 1) + UnevaluatedDict(d, 2)
In [64]: l = Lambda(d, d[1] + d[2])
In [65]: l({1: x, 2: y})
Out[65]: x + y