【问题标题】:Sympy solve returns strange dictionary, when it should not return anySympy解决返回奇怪的字典,当它不应该返回任何
【发布时间】:2022-01-10 14:41:08
【问题描述】:

这个问题可能与:

Python Sympy solve returns list vs. dictionary

Are quoted dictionary keys an absolute must?

我有这个 Sympy 代码,这是我第一次尝试 SymPy 库:

import sympy as sym
from sympy.parsing.sympy_parser import parse_expr

from sympy import symbols, Eq, solve



class FunZ:
    
    def __init__(self, f):  
  
        self.x, self.y  = sym.symbols('x y')
        
        self.f = parse_expr(f)
        
        # print('f : ', self.f)
        
    def evalu(self, xx, yy):
    
        return float(self.f.subs({self.x: xx, self.y: yy}).evalf())
    

    def derX(self, xx, yy):        
        
        self.dx = sym.diff(self.f, self.x)
        
        # print('dx : ', self.dx)
        
        return float(self.dx.subs({self.x: xx, self.y: yy}).evalf())
    
    def derY(self, xx, yy):
        
        self.dy = sym.diff(self.f, self.y)
        
        # print('dy :', self.dy)
        
        return float(self.dy.subs({self.x: xx, self.y: yy}).evalf())
    
    def derXY(self, xx, yy):
        
        return [float(self.derX(xx, yy)), float(self.derY(xx, yy))]
    
    def minim(self):
        
        self.dx = sym.diff(self.f, self.x)
        self.dy = sym.diff(self.f, self.y)
        print('dx : ', self.dx)
        print('dy : ', self.dy)
        
        eq1 = Eq(self.dx ,0)
        
        eq2 = Eq(self.dy ,0)
        
        solu = solve((eq1,eq2), (self.x, self.y), dict = False) #### HERE dict = False
        
        print(solu, type(solu))
        

        
        return solu 
    
funz = FunZ('x**2 + y**2 + 2*y + 2')

dict_min = funz.minim()

print(dict_min, type(dict_min))

for keys in dict_min:
    print('key : ', keys, 'value : ',  dict_min[keys])

print('values :' , dict_min.values())    

# print(dict_min[x]) ###### ---> NameError: name 'x' is not defined

print(dict_min['x']) ####### -----> KeyError: 'x'

我的输出看起来像:

dx :  2*x
dy :  2*y + 2
{x: 0, y: -1} <class 'dict'>
{x: 0, y: -1} <class 'dict'>
key :  x value :  0
key :  y value :  -1
values : dict_values([0, -1])
Traceback (most recent call last):

  File .....", line 88, in <module>
    print(dict_min['x']) ####### -----> KeyError: 'x'

KeyError: 'x'

    print(dict_min[x]) ###### ---> NameError: name 'x' is not defined

NameError: name 'x' is not defined

我可以用print('values :' , list(dict_min.values())) 得到x,y ---> values : [0, -1]

如果我在 solu = solve((eq1,eq2), (self.x, self.y), dict = True) 中将标志 dict 设置为 True,我会得到 [{x: 0, y: -1}] &lt;class 'list'&gt; 作为结果

知道发生了什么吗?它与我如何定义我的 Funz 类有关吗?结果对我来说似乎是合理的,但是这个 dict 东西让我发疯了。

【问题讨论】:

    标签: python python-3.x dictionary sympy


    【解决方案1】:

    您无法通过dict_min[x]dict_min["x"] 访问,因为x 的类型为sympy.core.symbol.Symbol。这个字典的键是sympy.core.symbol.Symbol类型的。

    dict_min[x] 不起作用,因为您的代码中没有定义 x 变量。

    dict_min["x"] 不起作用,因为在这里您将x 定义为string,但dict_min 中名为x 的键的类型为sympy.core.symbol.Symbol

    你的课没有问题。

    但是,您可以这样做:

    dict_min[funz.x]
    

    或:

    x = funz.x
    dict_min[x]
    

    所以,dict_min 不是 sympy 中的一个奇怪的 dict 类型,这是一个经典的 Python dict,其中键的类型是 sympy.core.symbol.Symbol。键是方程式的符号。可能是因为你的符号 xy 是在你的类中定义的,并且是通过 sym.symbols('x y') 定义的。

    如果您想始终获得list

    minim 中,您应该设置dict=True 而不是False。通过这样做,您将“始终获得解决方案映射列表”(https://docs.sympy.org/latest/modules/solvers/solvers.html)。 是的,dict=True 的目标是确保返回的变量是list 类型。我同意这可能有点奇怪。

    solve()的源码中关于这个标志的一些信息:https://github.com/sympy/sympy/blob/master/sympy/solvers/solvers.py#L406

    这是标志is_dict的效果:https://github.com/sympy/sympy/blob/master/sympy/solvers/solvers.py#L1249

    至于 sympy 1.9。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-20
      • 1970-01-01
      • 2020-01-24
      • 2020-08-10
      • 1970-01-01
      • 1970-01-01
      • 2019-07-05
      • 2017-07-04
      相关资源
      最近更新 更多