Reputation: 34884
I have a dictionary. Each key is represented in one of 2 ways: short and long. I want to get the values of some of they keys. I can do this:
d = dict(....)
a = d["a"] or d["aaa"]
b = d["b"] or d["bbb"]
But it throws an exception when the key "a
" doesn't exist, so it won't call d["aaa"]
even it must exist if d["a"]
doesn't. It can be solved easily, I know, but how can I do that in an elegant way?
Upvotes: 0
Views: 69
Reputation: 4446
You can use the get method of a dictionary and provide a default value:
d.get("a", None)
This will return d["a"] if "a" is a key or None otherwise
Upvotes: 1
Reputation: 214959
If you often use such a structure, you can have a small dict
wrapper similar to this:
class altdict(dict):
def __getitem__(self, item):
if isinstance(item, (tuple, list)):
for p in item:
try:
return self[p]
except KeyError:
pass
raise KeyError, item
return dict.__getitem__(self, item)
and then
d = altdict({
'a' :'aaa!',
'bbb' :'bbb!',
})
print d['a', 'aaa'] # aaa!
print d['b', 'bbb'] # bbb!
print d['c', 'ccc'] # KeyError
Note that this works with arbitrary lists of "alternate" keys:
d['B', 'Bill', 'William'] # pretty nice
while a .get
solution will turn into a nightmare very quickly:
d.get('a', d.get('b', d.get('c'))) # wtf?
Upvotes: 2
Reputation: 18685
you can use dict.get:
a = d.get("a", d.get("aaa"))
b = d.get("b", d.get("bbb"))
Note however that this will do a lookup of "aaa"
and "bbb"
even if "a"
and "b"
exist.
This works also (because or
works e.g. for None
and str
etc.):
a = d.get("a") or d.get("aaa")
and does not do a second lookup if the first one succeeds.
Note that this does NOT work if None
is a possible value associated to a key in your dict.
As @TimPietzcker points out, if you don't have None
as a possible value, you can do:
a = d.get("a") or d["aaa"]
in order to get an exception if both keys do not exist.
Upvotes: 2