Lambdas在容器上操作同情

时间:2014-09-04 15:38:09

标签: python 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

似乎同情的lambda只能在符号上操作,而不是容器。这可能吗?如果是的话,我该怎么办呢?

谢谢!

1 个答案:

答案 0 :(得分:0)

要制作Lambda,您需要一些无价值的东西。 d[1]立即评估Dict(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