Is there anything better than dict.get (<thing>, dict.get (<other>))?

In python

>>> x = {'spam': 'a lot'}
>>> x.get('eggs', x.get('spam'))
'a lot'

But something seems uncomfortable with regard to combination .get().

Is there a better way to say: "It could be one of two keys, I don't care, just give me the meaning"?

+4
source share
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
source

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

, , , :

result = myDict['eggs'] if 'eggs' in myDict else myDict.get('spam')

, , if.

result = myDict.get('eggs', 'fail')
if result == 'fail':
    result = myDict.get('spam')

- , ?

+1

Stick answer, , , ( " " ). : - . .

class MyDict(dict):
    def get(self, first_key, second_key, default=None):
        if first_key in self:
            return self[first_key]
        elif second_key in self:
            return self[second_key]
        else:
            return default

x = MyDict({"spam":"a lot"})
print x.get("eggs","spam")
# "a lot"    
+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
source

Source: https://habr.com/ru/post/1530670/


All Articles