【发布时间】:2011-02-04 04:50:51
【问题描述】:
a=['123','2',4]
b=a[4] or 'sss'
print b
我想在列表索引超出范围时获取默认值(此处为:'sss')。
我该怎么做?
【问题讨论】:
标签: python list syntax default-value
a=['123','2',4]
b=a[4] or 'sss'
print b
我想在列表索引超出范围时获取默认值(此处为:'sss')。
我该怎么做?
【问题讨论】:
标签: python list syntax default-value
本着“请求宽恕,而不是许可”的 Python 精神,这里有一种方法:
try:
b = a[4]
except IndexError:
b = 'sss'
【讨论】:
try:
b = a[4]
except IndexError:
b = 'sss'
一种更简洁的方式(仅当您使用字典时才有效):
b = a.get(4,"sss") # exact same thing as above
这是您可能喜欢的另一种方式(同样,仅适用于 dicts):
b = a.setdefault(4,"sss") # if a[4] exists, returns that, otherwise sets a[4] to "sss" and returns "sss"
【讨论】:
except: 定义例外。例如,当变量a 未定义时,也会触发您的异常。
except 是邪恶的。最好说except IndexError
使用 try/catch?
try:
b=a[4]
except IndexError:
b='sss'
【讨论】:
本着“请求许可,而不是宽恕”的非 Python 精神,这里有另一种方式:
b = a[4] if len(a) > 4 else 'sss'
【讨论】:
您还可以为这些情况定义一个小辅助函数:
def default(x, e, y):
try:
return x()
except e:
return y
它返回函数x的返回值,除非它引发了e类型的异常;在这种情况下,它返回值y。用法:
b = default(lambda: a[4], IndexError, 'sss')
编辑:让它只捕获一种指定类型的异常。
仍然欢迎提出改进建议!
【讨论】:
except 令人担忧
我完全赞成请求许可(即我不喜欢 try...except 方法)。但是,将代码封装在方法中时会变得更加简洁:
def get_at(array, index, default):
if index < 0: index += len(array)
if index < 0: raise IndexError('list index out of range')
return array[index] if index < len(a) else default
b = get_at(a, 4, 'sss')
【讨论】:
mylist[-1] 应该只获取最后一个元素,但是您的“请求许可”get_at 代码不会表现得像那样。这表明“请求许可”只是错误理念的众多原因之一:您正在检查的内容可能与系统将执行的内容不匹配。即,您不仅系统地尝试重复系统为您完成的工作,而且您很容易将那些额外的重复工作弄错。 “请求宽恕”要好得多。
def get_at(array, index, default): try: return array[index] except IndexError: return default,你可以侥幸逃脱
由于这是谷歌的热门搜索,可能还值得一提的是,标准的“collections”包有一个“defaultdict”,它为这个问题提供了更灵活的解决方案。
你可以做一些整洁的事情,例如:
twodee = collections.defaultdict(dict)
twodee["the horizontal"]["the vertical"] = "we control"
【讨论】:
您可以创建自己的列表类:
class MyList(list):
def get(self, index, default=None):
return self[index] if len(self) > index else default
你可以这样使用它:
>>> l = MyList(['a', 'b', 'c'])
>>> l.get(1)
'b'
>>> l.get(9, 'no')
'no'
【讨论】:
对于您想要第一个元素的常见情况,您可以这样做
next(iter([1, 2, 3]), None)
我用它来“解包”一个列表,可能是在过滤它之后。
next((x for x in [1, 3, 5] if x % 2 == 0), None)
或
cur.execute("SELECT field FROM table")
next(cur.fetchone(), None)
【讨论】:
在 Python 中,美胜于丑
代码高尔夫方法,使用切片和解包(不确定这在 4 年前是否有效,但它在 python 2.7 + 3.3 中)
b,=a[4:5] or ['sss']
比包装函数或 try-catch 恕我直言更好,但对初学者来说很吓人。就我个人而言,我发现元组解包比列表更性感[#]
使用切片而不拆包:
b = a[4] if a[4:] else 'sss'
或者,如果您必须经常这样做,并且不介意制作字典
d = dict(enumerate(a))
b=d.get(4,'sss')
【讨论】:
a[4:5] 一起使用不再好......
using splicing without unpacking 对我有用,否则返回的元素是大小为 1 的列表,而不是标量。
b,=a[4:] or 'sss',和b=a[4:] or 'sss'一样
a,您将在 b 中获得 2 个元素。
b, = a[-1:] or ['default value']
另一种方式:
b = (a[4:]+['sss'])[0]
【讨论】:
a[4:] 从(包括)索引 4 创建一个元素列表。这会导致一个空列表。 [1, 2, 3][999:] == [] 切片操作就是这样。如果 a 是 ['123', '2', 4, 5, 6],它将返回 [5, 6] 。然后他添加元素“sss”,创建一个新列表,在本例中为['sss']。最后一步[0] 只取第一个元素,因此返回'sss',但如果有这样一个元素,则会返回a[4]`
4 in a 询问4 是否在列表中作为值,而不是键!
如果您正在寻找一种可维护的方法来获取索引运算符的默认值,我发现以下方法很有用:
如果您从 operator 模块覆盖 operator.getitem 以添加可选的默认参数,您将获得与原始参数相同的行为,同时保持向后兼容性。
def getitem(iterable, index, default=None):
import operator
try:
return operator.getitem(iterable, index)
except IndexError:
return default
【讨论】:
如果您正在寻找减少字符长度的快速技巧,您可以试试这个。
a=['123','2',4]
a.append('sss') #Default value
n=5 #Index you want to access
max_index=len(a)-1
b=a[min(max_index, n)]
print(b)
但是这个技巧只有在你不想再修改列表时才有用
【讨论】: