Elegant way to unpack limited dict values into local variables in Python

Question:

I’m looking for an elegant way to extract some values from a Python dict into local values.

Something equivalent to this, but cleaner for a longer list of values, and for longer key/variable names:

d = { 'foo': 1, 'bar': 2, 'extra': 3 }
foo, bar = d['foo'], d['bar']

I was originally hoping for something like the following:

foo, bar = d.get_tuple('foo', 'bar')

I can easily write a function which isn’t bad:

def get_selected_values(d, *args):
    return [d[arg] for arg in args]

foo, bar = get_selected_values(d, 'foo', 'bar')

But I keep having the sneaking suspicion that there is some other builtin way.

Asked By: DonGar

||

Answers:

Somewhat horrible, but:

globals().update((k, v) for k, v in d.iteritems() if k in ['foo', 'bar'])

Note, that while this is possible – it’s something you don’t really want to be doing as you’ll be polluting a namespace that should just be left inside the dict itself…

Answered By: Jon Clements

Well, if you know the names ahead of time, you can just do as you suggest.

If you don’t know them ahead of time, then stick with using the dict – that’s what they’re for.

If you insist, an alternative would be:

varobj = object()
for k,v in d.iteritems(): setattr(varobj,k,v)

After which, keys will be variables on varobj.

Answered By: Marcin

You can do something like

foo, bar = map(d.get, ('foo', 'bar'))

or

foo, bar = itemgetter('foo', 'bar')(d)

This may save some typing, but essentially is the same as what you are doing (which is a good thing).

Answered By: Lev Levitsky

The elegant solution:

d = { "foo": 123, "bar": 456, None: 789 }
foo, bar, baz = d.values()  # 123, 456, 789

Notice that keys are not used, so be sure to get the order of your variables right, i.e. they must match the order that the keys were inserted into the map (this ordering is guaranteed since Python 3.6). If in doubt about ordering, use the other methods.

Answered By: Tronic

If you’re looking for elegance with performance across python versions, sadly I don’t think you’re gonna get any better than:

unpack = lambda a,b,c,**kw: (a,b,c) # static

d = dict( a=1, b=2, c=3, d=4, e=5 )

a,b,c = unpack(**d)

working examples:

>>> unpack = lambda a,b,c,**kw: (a,b,c)
>>> d = dict( a=1, b=2, c=3, d=4, e=5, f=6, g=7 )
>>> a,b,c = unpack(**d)
>>> 
>>> unpack(**d)
(1, 2, 3)

you can also unpack the difference that would otherwise be discarded:

>>> unpackextra = lambda a,b,c,**kw: (a,b,c,kw)
>>> a,b,c,extra = unpackextra(**d)
>>> 
>>> unpackextra(**d)
(1, 2, 3, {'f': 6, 'd': 4, 'e': 5, 'g': 7})

arguments are static though, so the use case should be specific to whatever your intents are. 😉

>>> unpack2 = lambda a,b,c,d,e,f,**kw: (a,b,c,d,e,f) # static
>>> 
>>> unpack2(**d)
(1, 2, 3, 4, 5, 6)
>>> 
Answered By: Tcll
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.