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

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

当前回答

你可以做的一件合理的事情是将列表转换为字典,然后用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')

其他回答

这不是一个非常通用的解决方案,但我有一个情况,我需要一个长度为3到5的列表(有一个保护if),并且我将值分解为命名变量。我找到了一个简单而简洁的方法:

foo = (argv + [None, None])[3]
bar = (argv + [None, None])[4]

现在foo和bar是列表中的第4和第5个值,如果没有那么多值,则为None。

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方法。

字典是用来查资料的。询问条目是否存在是有意义的。列表通常是迭代的。通常不会问L[10]是否存在,而是问L的长度是否为11。

你可以做的一件合理的事情是将列表转换为字典,然后用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')

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

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