在Python中,
>>> x = {'spam': 'a lot'}
>>> x.get('eggs', x.get('spam'))
'a lot'
但.get()
组合似乎很尴尬。
有没有更好的方式说,“这可能是两个关键之一,我不在乎哪个,只是给我价值”?
答案 0 :(得分:4)
我能想到的最“正确”的解决方案也是最丑陋的。太糟糕了。我的两个标准:
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
答案 1 :(得分:1)
我想我会倾向于这样做,因为它可能更具可读性:
>>> 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
答案 2 :(得分: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')
有什么不利于像这样分手吗?
答案 3 :(得分:1)
我喜欢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"
答案 4 :(得分:-1)
map
和filter
:
>>> 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']