繁体   English   中英

有没有比dict.get更好的东西(<thing>,dict.get(<other>))?

[英]Is there something better than dict.get(<thing>, dict.get(<other>))?

在Python中,

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

但是.get()组合似乎很尴尬。

有没有更好的方式来说,“这可能是两个关键之一,我不关心哪个,只是给我价值”?

我能想出的最“正确”的解决方案也是最丑陋的。 太糟糕了。 我的两个标准:

  • 避免0 or None角情况
  • 如果存在一个密钥则短路

尽管它很丑陋,但这实际上是最快的执行:

x['eggs'] if 'eggs' in x else x.get('spam')

timeit结果:

>>> 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

我想我会倾向于这样做,因为它可能更具可读性:

>>> 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

如果你只是在寻找一个单行,我相信已经发布的三元包含它:

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

如果你只是在寻找可读的答案,我想你只是去找if语句。

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

有什么不利于像这样分手吗?

我喜欢Stick的答案,但如果你要做的事情超过两次(遵循“三规则”),我会将它包装在一个类中。 另外:速度不应该是第一个问题 - 除非实际需要。 简单易懂。

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"    

使用mapfilter

>>> x = {'spam': 'a lot'}
>>> filter(None, map(x.get, ('eggs', 'spam'))) # [0]
['a lot']

列表理解:

>>> [x.get(k) for k in ('eggs', 'spam') if k in x]
['a lot']

在需要检查两个以上的键时非常有用:

>>> filter(None, map(x.get, ('eggs', 'foo', 'bar', 'spam')))
['a lot']

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM