Is there anything better than dict.get (<thing>, dict.get (<other>))?
5 answers
The most “right” solution I can come up with is also the ugliest. This sucks. My two criteria:
- Avoid the edge case
0 or None - Short circuit if one key exists
Despite its ugliness, this is actually the fastest execution:
x['eggs'] if 'eggs' in x else x.get('spam')
timeit results:
>>> op = lambda: x.get('eggs', x.get('spam'))
>>> aaron = lambda: x.get('eggs') or x.get('spam')
>>> ndpu = lambda: filter(None, map(x.get, ['eggs', 'spam']))[0]
>>> mhlester = lambda: x['eggs'] if 'eggs' in x else x.get('spam')
>>>
>>> timeit(op, number=100000)
0.04057041245972073
>>> timeit(aaron, number=100000)
0.04477326960257777
>>> timeit(ndpu, number=100000)
0.13210876799140614
>>> timeit(mhlester, number=100000)
0.03425499248118058
+4
I think I would like to do this because it is perhaps a little readable:
>>> x = {'spam': 'a lot'}
>>> results = x.get('eggs') or x.get('spam')
>>> results
'a lot'
, , , or .
, , x ['eggs'] , ( , ):
>>> results = 0 or 'a lot'
>>> results
'a lot'
>>> results = '' or 'a lot'
>>> results
'a lot'
:
>>> results = '' or None
>>> print(results)
None
+1
C mapand filter:
>>> x = {'spam': 'a lot'}
>>> filter(None, map(x.get, ('eggs', 'spam'))) # [0]
['a lot']
with a list:
>>> [x.get(k) for k in ('eggs', 'spam') if k in x]
['a lot']
can be useful when you need to check more than two keys:
>>> filter(None, map(x.get, ('eggs', 'foo', 'bar', 'spam')))
['a lot']
-1