Divide a dictionary into variables [duplicate]

Solution 1:

The existing answers will work, but they're all essentially re-implementing a function that already exists in the Python standard library: operator.itemgetter()

From the docs:

Return a callable object that fetches item from its operand using the operand’s __getitem__() method. If multiple items are specified, returns a tuple of lookup values. For example:

After f = itemgetter(2), the call f(r) returns r[2].

After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3]).


In other words, your destructured dict assignment becomes something like:

from operator import itemgetter

d = {'key_1': 'value_a', 'key_2': 'value_b'}
key_1, key_2 = itemgetter('key_1', 'key_2')(d)

# prints "Key 1: value_a, Key 2: value_b"
print("Key 1: {}, Key 2: {}".format(key_1, key_2))

Solution 2:

Problem is that dicts are unordered, so you can't use simple unpacking of d.values(). You could of course first sort the dict by key, then unpack the values:

# Note: in python 3, items() functions as iteritems() did
#       in older versions of Python; use it instead
ds = sorted(d.iteritems())
name0, name1, name2..., namen = [v[1] for v in ds]

You could also, at least within an object, do something like:

for k, v in dict.iteritems():
    setattr(self, k, v)

Additionally, as I mentioned in the comment above, if you can get all your logic that needs your unpacked dictionary as variables in to a function, you could do:

def func(**kwargs):
    # Do stuff with labeled args

func(**d)

Solution 3:

A solution which has not been mentionned before would be

dictget = lambda d, *k: [d[i] for i in k]

and then use it:

key_1, key_2 = dictget(d, 'key_1', 'key_2')

whose advantage is that it is quite readable even with more variables to be retrieved.

Even more readable, however, would be a "real" function such as

def dictget(d, *k):
    """Get the values corresponding to the given keys in the provided dict."""
    return [d[i] for i in k]
    # or maybe
    return (d[i] for i in k) # if we suppose that we have bigger sets of result
    # or, equivalent to this
    for i in k:
        yield d[i]

which as well supports commenting with a docstring and is to be preferred.

Solution 4:

var1, var2 = (lambda key1, key2: (key1, key2))(**d)

If you want to give anyone reading your code a headache you can use anonymous function to unpack values like this.