Turn the dictionary keys into variable names with same values in Python from .mat Matlab files using scipy.io.loadmat

StackOverflow https://stackoverflow.com/questions/6369535

Question

I am trying to take a basic dictionary temp = {'key':array([1,2])} loaded from a .mat file with scipy.io.loadmat. Turn the keys in the Python dictionary file returned by loadmat() into variable names with values the same as the representing keys.

So for example:

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

turned into

key = array([1,2])

I know how to grab the keys with temp.keys(). Then grabbing the items is easy but how do I force the list of strings in temp.keys() to be variable names instead of strings.

I hope this makes sense but this is probably really easy I just can't think how to do it.

Cheers

Was it helpful?

Solution

In python, method parameters can be passed as dictionnaries with the ** magic:

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

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

my_func(**temp)

>>> array([1,2])

OTHER TIPS

The best thing to do is to use temp['key']. To answer the question, however, you could use the exec function. The benefits of doing it this way is that you can do this don't have to hard code any variable names or confine yourself to work inside a function.

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]])

NOTE : This will only work if you have imported the specific function from the modules. If you don't want to do this because of code practice or the sheer volume of function that you would need to import, you could write a function to concatenate the module name in front of the entry. Output is the same as the previous example.

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)))

While this isn't the best code practice, It works well for all of the examples I tested.

A better way may be to stuff the data to a separate object:

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

This is about as easy to use interactively, and does not require any magic. This should be OK for Matlab-users, too.

EDIT: turns out the stuff below doesn't actually work most of the time. Too bad, so much for magic.

If you want to meddle with magic, though, you can do something like

locals().update(somedict)

This will work fine interactively, and you can even hide the access to locals() inside the loader function by messing with sys._getframe().f_back.f_locals.

However, this will not work in functions:

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

The point is that a above is bound to global variable at compile time, and so Python does not try looking it up in among local variables.

While I would just recommend using the dictionary directly and accessing the arrays like temp['key'], if you knew all of the variable names ahead of time you could write a function to extract them to individual variables:

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top