问题:为什么列表没有像字典一样安全的“获取”方法?
为什么列表没有像字典一样安全的“获取”方法?
>>> 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
回答 0
最终,它可能没有一个安全的.get
方法,因为a dict
是一个关联集合(值与名称相关联),在这种情况下,检查键是否存在(并返回其值)而不抛出异常是非常低效的,而这是非常琐碎的避免异常访问列表元素(因为该len
方法非常快)。该.get
方法允许您查询与名称关联的值,而不直接访问字典中的第37个项目(这更像是您要查询的列表中的内容)。
当然,您可以自己轻松实现此目的:
def safe_list_get (l, idx, default):
try:
return l[idx]
except IndexError:
return default
您甚至可以在中将其Monkey修补到__builtins__.list
构造函数上__main__
,但是由于大多数代码不使用它,因此更改的普及程度较小。如果您只想将此代码与自己的代码创建的列表一起使用,则可以简单地子类化list
并添加get
方法。
回答 1
如果您想要第一个元素,例如 my_list.get(0)
>>> my_list = [1,2,3]
>>> next(iter(my_list), 'fail')
1
>>> my_list = []
>>> next(iter(my_list), 'fail')
'fail'
我知道这并非您真正要求的,但可能会帮助其他人。
回答 2
可能是因为它对列表语义没有多大意义。但是,您可以通过子类化轻松创建自己的类。
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()
回答 3
代替使用.get,这样使用列表应该可以。只是用法上的差异。
>>> l = [1]
>>> l[10] if 10 < len(l) else 'fail'
'fail'
回答 4
试试这个:
>>> i = 3
>>> a = [1, 2, 3, 4]
>>> next(iter(a[i:]), 'fail')
4
>>> next(iter(a[i + 1:]), 'fail')
'fail'
回答 5
对于“单线”粉丝…
如果需要列表的第一个元素,或者如果列表为空,则需要默认值,请尝试:
liste = ['a', 'b', 'c']
value = (liste[0:1] or ('default',))[0]
print(value)
退货 a
和
liste = []
value = (liste[0:1] or ('default',))[0]
print(value)
退货 default
其他元素的示例…
liste = ['a', 'b', 'c']
print(liste[0:1]) # returns ['a']
print(liste[1:2]) # returns ['b']
print(liste[2:3]) # returns ['c']
默认回退…
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
经过测试 Python 3.6.0 (v3.6.0:41df79263a11, Dec 22 2016, 17:23:13)
回答 6
最好的办法是将列表转换成字典,然后使用get方法访问它:
>>> my_list = ['a', 'b', 'c', 'd', 'e']
>>> my_dict = dict(enumerate(my_list))
>>> print my_dict
{0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e'}
>>> my_dict.get(2)
'c'
>>> my_dict.get(10, 'N/A')
回答 7
因此,我对此进行了更多研究,结果发现没有任何针对此的东西。当我找到list.index(value)时,我感到很兴奋,它返回指定项目的索引,但是没有什么可用于获取特定索引处的值的。因此,如果您不想使用safe_list_get解决方案,我认为这是相当不错的。以下是一些liner 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
还没有进行基准测试以了解最快的方法。
回答 8
字典用于查找。询问条目是否存在是很有意义的。列表通常是迭代的。通常不问L [10]是否存在,而是问L的长度是否为11。
回答 9
您的用例基本上只与固定长度的数组和矩阵有关,这样您就可以知道它们有多长时间。在这种情况下,通常还需要在手动将它们填充为None或0之前创建它们,以便实际上您将使用的任何索引都已经存在。
你可以这样说:我经常在字典上需要.get()。作为一名全职程序员十年后,我认为我从不需要它了。:)