Sympy 解决 returns 奇怪的字典,当它不应该 return any
Sympy solve returns strange dictionary, when it should not return any
这个问题可能与:
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)
中将标志字典设置为 True,我将得到 [{x: 0, y: -1}] <class 'list'>
结果
知道发生了什么事吗?这与我如何定义 Funz class 有关吗?结果对我来说似乎是合理的,但是这个 dict 的东西让我发疯。
您无法通过 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
.
你的class没有问题。
但是,您可以这样做:
dict_min[funz.x]
或:
x = funz.x
dict_min[x]
所以,dict_min
不是来自 sympy 的一个奇怪的 dict
类型,它是一个 classic Python dict
类型的键是 sympy.core.symbol.Symbol
。键是方程式的符号。也许这令人困惑,因为你的符号 x
和 y
是在你的 class 中定义的,并通过 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.
这个问题可能与:
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)
中将标志字典设置为 True,我将得到 [{x: 0, y: -1}] <class 'list'>
结果
知道发生了什么事吗?这与我如何定义 Funz class 有关吗?结果对我来说似乎是合理的,但是这个 dict 的东西让我发疯。
您无法通过 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
.
你的class没有问题。
但是,您可以这样做:
dict_min[funz.x]
或:
x = funz.x
dict_min[x]
所以,dict_min
不是来自 sympy 的一个奇怪的 dict
类型,它是一个 classic Python dict
类型的键是 sympy.core.symbol.Symbol
。键是方程式的符号。也许这令人困惑,因为你的符号 x
和 y
是在你的 class 中定义的,并通过 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.