8

我正在尝试使用 scipy.io.loadmat 从 .mat 文件加载基本字典 temp = {'key':array([1,2])}。将 loadmat() 返回的 Python 字典文件中的键转换为与表示键值相同的变量名。

例如:

temp = {'key':array([1,2])}

转换成

key = array([1,2])

我知道如何使用 temp.keys() 获取密钥。然后抓取项目很容易,但我如何强制 temp.keys() 中的字符串列表为变量名而不是字符串。

我希望这是有道理的,但这可能真的很容易,我只是想不出该怎么做。

干杯

4

6 回答 6

11

在 python 中,方法参数可以作为字典传递,具有以下**魔力:

def my_func(key=None):
   print key
   #do the real stuff

temp = {'key':array([1,2])}

my_func(**temp)

>>> array([1,2])
于 2011-06-16T10:16:03.073 回答
4

最好的办法是使用temp['key']. 但是,要回答这个问题,您可以使用该exec功能。这样做的好处是您可以这样做,而不必硬编码任何变量名或将自己限制在函数内部工作。

from numpy import array,matrix

temp = {'key':array([1,2]),'b': 4.3,'c': 'foo','d':matrix([2,2])}

for k in temp:
    exec('{KEY} = {VALUE}'.format(KEY = k, VALUE = repr(temp[k])))

>>> key
array([1, 2])
>>> b
4.3
>>> c
'foo'
>>> d
matrix([[2, 2]])

注意:这仅在您从模块中导入特定功能时才有效。如果您因为代码实践或需要导入的大量函数而不想这样做,您可以编写一个函数来连接条目前面的模块名称。输出与前面的示例相同。

import numpy as np,numpy

temp = {'key':np.array([1,2]),'b': 4.3,'c': 'foo','d':np.matrix([2,2])}

def exec_str(key,mydict):
    s = str(type(mydict[key]))
    if '.' in s:
        start = s.index("'") + 1
        end = s.index(".") + 1
        v = s[start:end:] + repr(mydict[key])
    else:
        v = repr(mydict[key])     
    return v

for k in temp:
    exec('{KEY} = {VALUE}'.format(KEY = k, VALUE = exec_str(k,temp)))

虽然这不是最佳代码实践,但它适用于我测试的所有示例。

于 2013-06-12T01:42:02.027 回答
2

更好的方法可能是将数据填充到单独的对象中:

class attrdict(dict):
    def __getattr__(self, k): return self[k]
    def __setattr__(self, k, v): self[k] = v

somedict = {'key': 123, 'stuff': 456}

data = attrdict(somedict)
print data.key
print data.stuff

这与交互使用一样容易,并且不需要任何魔法。这对 Matlab 用户来说也应该没问题。

编辑:结果下面的东西实际上大部分时间都不起作用。太糟糕了,魔法就这么多。

但是,如果你想插手魔法,你可以做类似的事情

locals().update(somedict)

这将以交互方式正常工作,您甚至可以locals()通过弄乱sys._getframe().f_back.f_locals.

但是,这在函数中不起作用:

def foo():
    locals().update({'a': 4})
    print a 

关键是a上面在编译时绑定到全局变量,所以 Python 不会尝试在局部变量中查找它。

于 2011-06-16T11:58:56.770 回答
1

正如 hdhagman 回答的那样,使用 exec() 更简单。我写了更简单的代码。

temp = {'key':[1,2]}

for k, v in temp.items():
    exec("%s = %s" % (k, v))

打印(键)=> [1,2]

于 2020-09-15T03:51:11.703 回答
1

上面的答案都不适用于 numpy 数组和其他非内置类型。但是,以下操作:

import numpy as np
temp = {'a':np.array([1,2]), 'b': 4.3, 'c': 'foo', 'd':np.matrix([2,2])}
for var in temp.keys():
    exec("{} = temp['{}']".format(var, var))

注意引号的顺序。这允许var在第一个实例中被视为变量,然后在第二个实例中被视为键,索引到temp字典中。

当然,关于危险的通常免责声明exec()仍然eval()适用,您应该只在您绝对信任的输入上运行它。

于 2021-06-16T17:21:34.850 回答
0

虽然我只建议直接使用字典并访问数组temp['key'],但如果您提前知道所有变量名称,您可以编写一个函数将它们提取到单个变量中:

def func(**kwargs):
    return kwargs['a'],kwargs['b']


temp = {'a':np.array([1,2]),'b':np.array([3,4])}
a,b = func(**temp)
del temp # get rid of temporary dict
于 2011-06-16T12:35:24.917 回答