在Python中,
>>> x = {'spam': 'a lot'}
>>> x.get('eggs', x.get('spam'))
'a lot'
但是使用 .get()
这种组合的方式似乎有些别扭。
有没有更好的方法来表达“这可能是两个键中的一个,我不在意哪一个,只想获取值”的意思呢?
在Python中,
>>> x = {'spam': 'a lot'}
>>> x.get('eggs', x.get('spam'))
'a lot'
但是使用 .get()
这种组合的方式似乎有些别扭。
有没有更好的方法来表达“这可能是两个键中的一个,我不在意哪一个,只想获取值”的意思呢?
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
x['eggs']
是 0
呢?我想要的是 0
,而不是 None
。 - mhlesterget
都保证会被调用。 - mhlester'很多'
! - John Yresult = myDict['eggs'] if 'eggs' in myDict else myDict.get('spam')
if
语句。result = myDict.get('eggs', 'fail')
if result == 'fail':
result = myDict.get('spam')
这样分割有什么不利之处吗?
myDict.get('eggs')
,因为如果你在代码的那个部分,'eggs'
已经被确认在myDict
中。这个答案类似于mhlester的答案,但是你还建议了一个更长的形式,在myDict['eggs']
实际上等于'fail'
的情况下是不正确的。此外,is
不是字符串相等的适当测试。两个非常长的字符串可以相等(使用==
),但不是相同的(使用is
)。 - John Yclass 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"
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']
[0]
,而在第二个例子中根本没有包括它?除了这些问题之外,我认为这个答案实际上是有用的,以防有许多可能的键需要检查。 - John Ymap
和filter
。 - John Y[0]
以增强通用性... 如果需要的话,仍然需要使用 if
。 - ndpuNone
。 - John Y
defaultdict
来解决这个问题? OP的版本会带来什么奇怪的副作用? - John Yx["spam"]
会改变get的行为。 - David EhrmannNone
;或(2)获取'eggs'或'spam'中的任意一个,无论哪个失败,都获取None
。你会使用哪个工厂函数来获得这些行为的defaultdict
? - John Yd['spam']
的值写入d['eggs']
,你可以像这样做:d = defaultdict(partial(d.get, 'spam'))
... - Corley Brigman