Превратите ключи словаря в имена переменных с такими же значениями в Python из файлов Matlab .mat с помощью scipy.io.loadmat - PullRequest
7 голосов
/ 16 июня 2011

Я пытаюсь взять базовый словарь temp = {'key': array ([1,2])}, загруженный из файла .mat с scipy.io.loadmat. Превратите ключи в файле словаря Python, возвращенные loadmat (), в имена переменных со значениями, совпадающими с соответствующими ключами.

Так, например:

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

превратился в

key = array([1,2])

Я знаю, как получить ключи с помощью temp.keys (). Затем захватить элементы легко, но как заставить список строк в temp.keys () быть именами переменных вместо строк.

Надеюсь, это имеет смысл, но, вероятно, это действительно просто, я просто не могу думать, как это сделать.

Приветствия

Ответы [ 4 ]

10 голосов
/ 16 июня 2011

В python параметры метода могут быть переданы в виде словарей с помощью ** magic:

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

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

my_func(**temp)

>>> array([1,2])
3 голосов
/ 12 июня 2013

Лучше всего использовать 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)))

Хотя это не лучшая практика кода, он работает хорошо для всех примеров, которые я тестировал.

2 голосов
/ 16 июня 2011

Лучшим способом может быть помещение данных в отдельный объект:

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 не пытается искать ее среди локальных переменных.

0 голосов
/ 16 июня 2011

Хотя я бы порекомендовал использовать словарь напрямую и обращаться к массивам, таким как 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
...