为什么列表没有像字典一样安全的“获取”方法?

>>> 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

当前回答

试试这个:

>>> i = 3
>>> a = [1, 2, 3, 4]
>>> next(iter(a[i:]), 'fail')
4
>>> next(iter(a[i + 1:]), 'fail')
'fail'

其他回答

所以我对此做了更多的研究,结果是没有什么特别的东西。当我找到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

还没有基准测试,看看什么是最快的。

如果你想要第一个元素,比如my_list.get(0)

>>> my_list = [1,2,3]
>>> next(iter(my_list), 'fail')
1
>>> my_list = []
>>> next(iter(my_list), 'fail')
'fail'

我知道这不是你想要的但也许能帮到别人。

您的用例基本上只与处理固定长度的数组和矩阵相关,以便您事先知道它们有多长。在这种情况下,通常还需要在手动填充None或0之前创建它们,这样实际上您将使用的任何索引都已经存在。

你可以说:我经常需要在字典上查找.get()。在做了十年的全职程序员之后,我认为我不需要把它列在清单上。:)

不要使用.get,像这样使用列表应该是可以的。只是用法上的不同。

>>> l = [1]
>>> l[10] if 10 < len(l) else 'fail'
'fail'

可能是因为它对列表语义没有多大意义。但是,您可以通过子类化轻松创建自己的子类。

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()