为什么列表没有像字典一样安全的“获取”方法?
>>> 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
当前回答
可能是因为它对列表语义没有多大意义。但是,您可以通过子类化轻松创建自己的子类。
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()
其他回答
不要使用.get,像这样使用列表应该是可以的。只是用法上的不同。
>>> l = [1]
>>> l[10] if 10 < len(l) else 'fail'
'fail'
字典是用来查资料的。询问条目是否存在是有意义的。列表通常是迭代的。通常不会问L[10]是否存在,而是问L的长度是否为11。
如果你
想要一个眼线, 宁愿不使用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)
''
这要归功于乔斯·安吉尔·希门尼斯和古斯·巴斯。
对于“在线”的粉丝们…
如果你想要列表的第一个元素,或者如果你想要一个默认值,如果列表是空的,尝试:
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)
Ultimately it probably doesn't have a safe .get method because a dict is an associative collection (values are associated with names) where it is inefficient to check if a key is present (and return its value) without throwing an exception, while it is super trivial to avoid exceptions accessing list elements (as the len method is very fast). The .get method allows you to query the value associated with a name, not directly access the 37th item in the dictionary (which would be more like what you're asking of your list).
当然,你可以很容易地实现自己:
def safe_list_get (l, idx, default):
try:
return l[idx]
except IndexError:
return default
你甚至可以monkeypatch它到__builtins__。__main__中的列表构造函数,但这将是一个不太普遍的变化,因为大多数代码不使用它。如果你只是想用你自己的代码创建的列表使用这个,你可以简单地子类list并添加get方法。