2014-09-04 88 views
1

在集装箱上运行,我想这样做在sympy如下:lambda表达式在sympy

In [1]: from sympy import symbols, Lambda In [2]: from sympy.core.containers import Dict In [3]: x, y = symbols('x y') In [4]: d = Dict({1:x, 2:y}) In [5]: f = Lambda(d, d[1] + d[2]) In [6]: f({1:10, 2:20}) Out[6]: 30

好像sympy的lambda表达式只能在符号但是操作,而不是容器。这可能吗?如果是这样,我该怎么办?

谢谢!

回答

0

要制作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