Превратите ключи словаря в имена переменных с одинаковыми значениями в Python из файлов Matlab.mat с помощью scipy.io.loadmat
Я пытаюсь взять базовый словарь temp = {'key':array([1,2])}, загруженный из файла.mat с scipy.io.loadmat. Превратите ключи в файле словаря Python, возвращаемые loadmat(), в имена переменных со значениями, совпадающими с соответствующими ключами.
Так, например:
temp = {'key':array([1,2])}
превратился в
key = array([1,2])
Я знаю, как получить ключи с помощью temp.keys(). Затем захватить элементы легко, но как заставить список строк в temp.keys () быть именами переменных вместо строк.
Я надеюсь, что это имеет смысл, но это, вероятно, действительно легко, я просто не могу думать, как это сделать.
ура
7 ответов
В python параметры метода могут передаваться как словари с **
магия:
def my_func(key=None):
print key
#do the real stuff
temp = {'key':array([1,2])}
my_func(**temp)
>>> array([1,2])
Лучше всего использовать 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)))
Хотя это не лучшая практика кода, она работает хорошо для всех примеров, которые я тестировал.
Лучшим способом может быть помещение данных в отдельный объект:
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 не пытается искать его среди локальных переменных.
Ни один из приведенных выше ответов не помог мне с массивами 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()
все еще применяется, и вы должны запускать это только при вводе, которому вы абсолютно доверяете.
Как ответил hdhagman, использовать exec () проще. Я пишу более простой код.
temp = {'ключ':[1,2]}
for k, v in temp.items():
exec("%s = %s" % (k, v))
печать (ключ) => [1,2]
У меня был тот же вопрос, и я попробовал этот код, основываясь на ответах других. Здесь я использовал Pickle вместо Matlab для хранения и извлечения данных.
Чтобы сохранить данные
x1=[2,4,6,8,10]
x2=[1,3,5,7,9]
x3='hello world'
vars={'x1':'x1','x2':'x2','x3':'x3'}
file='test.pickle'
f = open(file,'wb')
for key in vars.keys():
pickle.dump(eval(vars[key]),f)
del x1,x2,x3
прочитать из файла
s = open(file,'rb')
for k in vars:
exec('{KEY} = {VALUE}'.format(KEY = k, VALUE = repr(pickle.load(s))))
print(x1,x2,x3)
Хотя я бы просто рекомендовал использовать словарь напрямую и обращаться к таким массивам, как 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