67

What's the most succinct way of saying, in Python, "Give me dict['foo'] if it exists, and if not, give me this other value bar"? If I were using an object rather than a dictionary, I'd use getattr:

getattr(obj, 'foo', bar)

but this raises a key error if I try using a dictionary instead (a distinction I find unfortunate coming from JavaScript/CoffeeScript). Likewise, in JavaScript/CoffeeScript I'd just write

dict['foo'] || bar

but, again, this yields a KeyError. What to do? Something succinct, please!

mikej
  • 65,295
  • 17
  • 152
  • 131
Trevor Burnham
  • 76,828
  • 33
  • 160
  • 196

2 Answers2

109

dict.get(key, default) returns dict[key] if key in dict, else returns default.

Note that the default for default is None so if you say dict.get(key) and key is not in dict then this will just return None rather than raising a KeyError as happens when you use the [] key access notation.

mikej
  • 65,295
  • 17
  • 152
  • 131
  • Thanks, that's just what I was looking for! I think you just set a new speed record. – Trevor Burnham Jun 21 '10 at 23:44
  • Hey is it possible to do this only for a particular characteristic of key... [Here](http://stackoverflow.com/a/6467555/5961780), a value is only returned when 'key', or rather 'name', starts with the letter 'f'. – sbrm1 Oct 06 '16 at 03:52
5

Also take a look at collections module's defaultdict class. It's a dict for which you can specify what it must return when the key is not found. With it you can do things like:

class MyDefaultObj:
    def __init__(self):
        self.a = 1

from collections import defaultdict
d = defaultdict(MyDefaultObj)
i = d['NonExistentKey']
type(i)
<instance of class MyDefalutObj>

which allows you to use the familiar d[i] convention.

However, as mikej said, .get() also works, but here is the form closer to your JavaScript example:

d = {}
i = d.get('NonExistentKey') or MyDefaultObj()
# the reason this is slightly better than d.get('NonExistent', MyDefaultObj())
# is that instantiation of default value happens only when 'NonExistent' does not exist.
# With d.get('NonExistent', MyDefaultObj()) you spin up a default every time you .get()
type(i)
<instance of class MyDefalutObj>
ddotsenko
  • 4,926
  • 25
  • 24