Convert dictionary entries into variables

PythonDictionary

Python Problem Overview


Is there a Pythonic way to assign the values of a dictionary to its keys, in order to convert the dictionary entries into variables? I tried this out:

>>> d = {'a':1, 'b':2}
>>> for key,val in d.items():
        exec('exec(key)=val')
    	    
        exec(key)=val
      	         ^ 
        SyntaxError: invalid syntax

I am certain that the key-value pairs are correct because they were previously defined as variables by me before. I then stored these variables in a dictionary (as key-value pairs) and would like to reuse them in a different function. I could just define them all over again in the new function, but because I may have a dictionary with about 20 entries, I thought there may be a more efficient way of doing this.

Python Solutions


Solution 1 - Python

You can do it in a single line with:

>>> d = {'a': 1, 'b': 2}
>>> locals().update(d)
>>> a
1

However, you should be careful with how Python may optimize locals/globals access when using this trick.

Note

I think editing locals() like that is generally a bad idea. If you think globals() is a better alternative, think it twice! :-D

Instead, I would rather always use a namespace.

With Python 3 you can:

>>> from types import SimpleNamespace    
>>> d = {'a': 1, 'b': 2}
>>> n = SimpleNamespace(**d)
>>> n.a
1

If you are stuck with Python 2 or if you need to use some features missing in types.SimpleNamespace, you can also:

>>> from argparse import Namespace    
>>> d = {'a': 1, 'b': 2}
>>> n = Namespace(**d)
>>> n.a
1

If you are not expecting to modify your data, you may as well consider using collections.namedtuple, also available in Python 3.

Solution 2 - Python

This was what I was looking for:

>>> d = {'a':1, 'b':2}
>>> for key,val in d.items():
        exec(key + '=val')

Solution 3 - Python

You already have a perfectly good dictionary. Just use that. If you know what the keys are going to be, and you're absolutely sure this is a reasonable idea, you can do something like

a, b = d['a'], d['b']

but most of the time, you should just use the dictionary. (If using the dictionary is awkward, you are probably not organizing your data well; ask for help reorganizing it.)

Solution 4 - Python

you can use operator.itemgetter

>>> from operator import itemgetter
>>> d = {'a':1, 'b':2}
>>> a, b = itemgetter('a', 'b')(d)
>>> a
1
>>> b
2

Solution 5 - Python

Consider the "Bunch" solution in Python: load variables in a dict into namespace. Your variables end up as part of a new object, not locals, but you can treat them as variables instead of dict entries.

class Bunch(object):
    def __init__(self, adict):
        self.__dict__.update(adict)

d = {'a':1, 'b':2}
vars = Bunch(d)
print vars.a, vars.b

Solution 6 - Python

Python has great support for list unpacking, but not dict or object unpacking. The most unsurprising and Pythonic approach seems to be accessing each item by hand to build an intermediate tuple as described in this answer:

a, b = d['a'], d['b']

However, if you have a lot of properties, or variable names are long, it can get nasty to do:

great, wow, awesome = dictionary['great'], dictionary['wow'], dictionary['awesome']

For context, the JavaScript equivalent of the above (destructuring) is:

const {great, wow, awesome} = dictionary;

Here's an option that is a bit more dynamic:

>>> dictionary = dict(great=0, wow=1, awesome=2)
>>> great, wow, awesome = (dictionary[k] for k in ("great", "wow", "awesome"))
>>> great
0
>>> awesome
2

This is still verbose; you could write a function to abstract things a bit, but unfortunately you still have to type everything twice:

>>> def unpack(dct, *keys):
...     return (dct[k] for k in keys)
... 
>>> dictionary = dict(great=0, wow=1, awesome=2)
>>> great, wow, awesome = unpack(dictionary, "great", "wow", "awesome")

You can generalize this to work on objects too:

>>> def unpack(x, *keys):
...     if isinstance(x, dict):
...         return (x[k] for k in keys)
...     return (getattr(x, k) for k in keys)
...
>>> from collections import namedtuple
>>> Foo = namedtuple("Foo", "a b c d e")
>>> foo = Foo(a=0, b=1, c=2, d=3, e=4)
>>> c, b, d, a = unpack(foo, "c", "b", "d", "a")
>>> d
3

After all is said and done, unpacking by hand on multiple lines is probably best for real production code that you need to be safe and comprehensible:

>>> great = dictionary["great"]
>>> wow = dictionary["wow"]
>>> awesome = dictionary["awesome"]

Solution 7 - Python

Use pandas:

import pandas as pd
var=pd.Series({'a':1, 'b':2})
#update both keys and variables
var.a=3
print(var.a,var['a'])

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionHappyPyView Question on Stackoverflow
Solution 1 - PythonPequeView Answer on Stackoverflow
Solution 2 - PythonHappyPyView Answer on Stackoverflow
Solution 3 - Pythonuser2357112View Answer on Stackoverflow
Solution 4 - PythonsuhailvsView Answer on Stackoverflow
Solution 5 - PythontdelaneyView Answer on Stackoverflow
Solution 6 - PythonggorlenView Answer on Stackoverflow
Solution 7 - PythonrestrepoView Answer on Stackoverflow