为什么列表没有像字典一样安全的“获取”方法?
>>> d = {'a':'b'}
>>> d['a']
'b'
>>> d['c']
KeyError: 'c'
>>> d.get('c', 'fail')
'fail'
>>> l = [1]
>>> l[10]
IndexError: list index out of range
为什么列表没有像字典一样安全的“获取”方法?
>>> d = {'a':'b'}
>>> d['a']
'b'
>>> d['c']
KeyError: 'c'
>>> d.get('c', 'fail')
'fail'
>>> l = [1]
>>> l[10]
IndexError: list index out of range
当前回答
如果你
想要一个眼线, 宁愿不使用try /,除非在您不需要的代码路径中 想要默认值为可选的,
你可以用这个:
list_get = lambda l, x, d=None: d if not l[x:x+1] else l[x]
用法如下:
>>> list_get(['foo'], 4) == None
True
>>> list_get(['hootenanny'], 4, 'ho down!')
'ho down!'
>>> list_get([''], 0)
''
其他回答
这不是一个非常通用的解决方案,但我有一个情况,我需要一个长度为3到5的列表(有一个保护if),并且我将值分解为命名变量。我找到了一个简单而简洁的方法:
foo = (argv + [None, None])[3]
bar = (argv + [None, None])[4]
现在foo和bar是列表中的第4和第5个值,如果没有那么多值,则为None。
所以我对此做了更多的研究,结果是没有什么特别的东西。当我找到list.index(value)时,我很兴奋,它返回指定项的索引,但没有任何东西用于获取特定索引的值。如果你不想使用safe_list_get解决方案,我认为这很好。下面是一些if语句,它们可以根据场景帮助你完成工作:
>>> x = [1, 2, 3]
>>> el = x[4] if len(x) > 4 else 'No'
>>> el
'No'
你也可以用None来代替No,这样更有意义。
>>> x = [1, 2, 3]
>>> i = 2
>>> el_i = x[i] if len(x) == i+1 else None
同样,如果您只想获取列表中的第一项或最后一项,也可以这样做
end_el = x[-1] if x else None
你也可以把它们变成函数,但是我仍然喜欢IndexError异常解决方案。我尝试了safe_list_get解决方案的简化版本,并使其更简单(没有默认值):
def list_get(l, i):
try:
return l[i]
except IndexError:
return None
还没有基准测试,看看什么是最快的。
如果你
想要一个眼线, 宁愿不使用try /,除非在您不需要的代码路径中 想要默认值为可选的,
你可以用这个:
list_get = lambda l, x, d=None: d if not l[x:x+1] else l[x]
用法如下:
>>> list_get(['foo'], 4) == None
True
>>> list_get(['hootenanny'], 4, 'ho down!')
'ho down!'
>>> list_get([''], 0)
''
可能是因为它对列表语义没有多大意义。但是,您可以通过子类化轻松创建自己的子类。
class safelist(list):
def get(self, index, default=None):
try:
return self.__getitem__(index)
except IndexError:
return default
def _test():
l = safelist(range(10))
print l.get(20, "oops")
if __name__ == "__main__":
_test()
这要归功于乔斯·安吉尔·希门尼斯和古斯·巴斯。
对于“在线”的粉丝们…
如果你想要列表的第一个元素,或者如果你想要一个默认值,如果列表是空的,尝试:
liste = ['a', 'b', 'c']
value = (liste[0:1] or ('default',))[0]
print(value)
返回一个
and
liste = []
value = (liste[0:1] or ('default',))[0]
print(value)
返回默认
其他元素的例子…
liste = ['a', 'b', 'c']
print(liste[0:1]) # returns ['a']
print(liste[1:2]) # returns ['b']
print(liste[2:3]) # returns ['c']
print(liste[3:4]) # returns []
默认的回退…
liste = ['a', 'b', 'c']
print((liste[0:1] or ('default',))[0]) # returns a
print((liste[1:2] or ('default',))[0]) # returns b
print((liste[2:3] or ('default',))[0]) # returns c
print((liste[3:4] or ('default',))[0]) # returns default
可能短:
liste = ['a', 'b', 'c']
value, = liste[:1] or ('default',)
print(value) # returns a
看起来你需要在等号前加逗号,等号和后面的括号。
更普遍的:
liste = ['a', 'b', 'c']
f = lambda l, x, d: l[x:x+1] and l[x] or d
print(f(liste, 0, 'default')) # returns a
print(f(liste, 1, 'default')) # returns b
print(f(liste, 2, 'default')) # returns c
print(f(liste, 3, 'default')) # returns default
使用Python 3.6.0进行测试(v3.6.0:41df79263a11, Dec 22 2016, 17:23:13)