我有一个字典,其中包含变量名称及其相应的值,我想动态分配
dict_ = {'var1':'cvx.Variable(3)', 'var2':'3'}
在我的代码中,我然后做
for k,v in dict_.iteritems():
exec("global %s;%s=%s" % (k,k,v))
print k, type(k)
对于整数变量,这有效,我得到 3 个类型"int",但是对于 var1(将 cvxpy 导入为 cvx(,我得到 k 类型"str"。我想去哪里
class 'cvxpy.expressions.variables.variable.Variable'
任何建议我做错了什么?
编辑:我正在接收字典条目作为字符串输入,例如
"var1 = cvx.Variable(3),var2 = 3"
然后我将其转换为字典
为什么不应该使用非字符串dict_
值:
如其文档中所述,%
运算符在与%s
格式一起使用时调用 str()
内置函数。
当在 cvxpy.Variable
实例上调用 str()
时,它会返回一个格式为 varX
的字符串,其中 X
是一个整数(我想是内存中创建的变量的索引(:
>>> import cvxpy
>>> x = cvxpy.Variable(3)
>>> str(x)
'var0'
不幸的是,这种格式恰好是你收到的字符串对其变量使用的命名召集。
定义dict_ = {'var1':cvx.Variable(3), 'var2':3}
不仅不能解决你的问题,而且可能会默默地成功,因为传递给str()
的 dict_['var1']
值可能会在你构建的赋值的右侧返回一个varX
值,该赋值引用了%
引用现有变量(在循环之前或通过传递给exec()
global
声明(。
相反,您的代码应该有效,您的问题肯定超出了您与我们共享的内容。
例如,我在机器上运行以下代码(Python 2.7.12(:
>>> import cvxpy
>>> cvxpy.__version__
'1.0.6'
>>> d = {'var1': 'cvxpy.Variable(3)', 'var2': '3'}
>>> for k, v in d.iteritems():
... s = 'global %s; %s = %s' % (k, k, v)
... print s
... exec(s)
...
global var1; var1 = cvxpy.Variable(3)
global var2; var2 = 3
>>> print var1, type(var1)
var0 <class 'cvxpy.expressions.variable.Variable'>
>>> print var2, type(var2)
3 <type 'int'>
请注意,print var1
打印var0
如上所述!
看起来这里的大多数注释和解决方案似乎都包含运行代码、字符串解析和exec
uted 代码之间的一些混淆:您要exec
的任何内容都应该是str
!如果不是,那么它将通过直接或间接调用内置str()
(就像你调用%
所做的那样(成为一个str
,因为exec
需要一个字符串。
如果字符串已按照您的建议正确格式化,您是否考虑过执行以下操作?
str_in = "var1 = cvx.Variable(3),var2 = 3"
exec(str_in.replace(',', ';'))
注意:在这里,我假设你在适当的范围内不需要global
但更多的字符串解析(split
,strip
,...(将使首先将变量声明为global
变得微不足道。
dict_ = {'var1':cvx.Variable(3), 'var2':3}
假设您希望var2
int
而不是str
.否则,当您将var1
的值括在引号中时,它将默认为 stringType
编辑: PicTo 关于您的实现是正确的,因为您使用的是%s
格式,您会自动将变量转换为字符串类型。可能更符合您正在寻找的内容是:
dict_ = {'var1':cvx.Variable(3), 'var2':3}
globals().update(dict_)
这会将变量放在全局范围内,并保持类型一致,假设您希望变量在全局范围内。如果你不这样做,locals()
支持相同的范式例:
>>> mydict = {'var1':3, 'var2': "happystring"}
>>> globals().update(dict_)
>>> var1
3
>>> var2
'happystring'