在Python中获取索引的默认值超出范围

zjm*_*126 71 python syntax list default-value

a=['123','2',4]
b=a[4] or 'sss'
print b
Run Code Online (Sandbox Code Playgroud)

我想在列表索引超出范围时获取默认值(此处为:) 'sss'.

我怎样才能做到这一点?

Tho*_*mas 87

在"请求宽恕,而不是许可"的Python精神中,这是一种方式:

try:
    b = a[4]
except IndexError:
    b = 'sss'
Run Code Online (Sandbox Code Playgroud)

  • 任何简单的方法? (29认同)
  • @KennyTM:他们有三种不同的选择.我想,这样最好的答案可以被投票到顶部,而糟糕的答案会消失在遗忘之中.它不是作为反复诱饵,实际上是公认的做法:http://meta.stackexchange.com/questions/21761/can-i-answer-a-question-multiple-times (9认同)
  • @zjm:这个*是一个简单的方法 (8认同)
  • 有必要跨越3个答案吗? (5认同)
  • 仅使用异常来返回默认值并不是一个好习惯,尽管这是一种简单(不简单)的方法。 (3认同)
  • 太丑了……真的吗?没有简单的方法吗? (3认同)
  • 这不是“简单”的方式,而是“Pythonic”的方式。我认为它在表达“简单”概念“如果项目不在列表中则返回默认值”方面不如字典使用“get(key,default_value)”那么好。我也不明白是什么让这个列表如此特别,以至于类似的抽象是禁忌。每个人都必须有自己的 lambda 序言。在我看来,这似乎是由于传统主义而永远被原谅的语言疏忽。 (3认同)
  • 如果你想要一个单行,那就把它放到一个小帮手函数中. (2认同)
  • 我想在列表中看到dicts的.get方法,当你使用get并且它不存在时它默认只返回None. (2认同)
  • 完全同意,应该为逻辑/算法而不是数据结构/内容保留例外。 (2认同)
  • 注意:这不适用于负索引,因为在 python 中负索引只是给你元素,它是后面的绝对值 (2认同)

Tho*_*mas 60

在"请求许可,而不是宽恕"的非Python精神中,这是另一种方式:

b = a[4] if len(a) > 4 else 'sss'
Run Code Online (Sandbox Code Playgroud)

  • 为什么要避免尝试/捕获? (4认同)
  • 正在使用它,很高兴看到可靠性确认.我倾向于尽量避免尝试(和捕捉). (2认同)

005*_*005 21

在Python的精神中,美丽胜过丑陋

代码高尔夫球方法,使用切片和拆包

b,=a[4:5] or ['sss']
Run Code Online (Sandbox Code Playgroud)

比包装函数更好,或者尝试捕获恕我直言,但对于初学者来说是令人生畏的.就个人而言,我发现元组拆包比列表更性感[#]

使用切片而不解压缩:

b = a[4] if a[4:] else 'sss'
Run Code Online (Sandbox Code Playgroud)

或者,如果你经常这样做,并且不介意制作字典

d = dict(enumerate(a))
b=d.get(4,'sss')
Run Code Online (Sandbox Code Playgroud)

  • `在不解包的情况下使用拼接` 对我有用,否则,返回的元素是大小为 1 的列表,而不是标量。 (2认同)
  • 适合高尔夫球手的较短的一个:`b=[*a[4:],'sss'][0]` (2认同)

mae*_*aep 16

其他方式:

b = (a[4:]+['sss'])[0]
Run Code Online (Sandbox Code Playgroud)

  • 实现这一目标的有趣方式.有点不可思议的一面. (4认同)
  • 好的,所以我喜欢不冗长。你能解释一下语法吗? (2认同)
  • `a[4:]` 创建一个元素列表,从(包括)索引 4 开始。这会导致一个空列表。`[1, 2, 3][999:] == []` 这就是切片操作的工作原理。如果 `a` 是 `['123', '2', 4, 5, 6]`,它将返回 [5, 6] 。然后他添加元素'sss',创建一个新列表,在本例中为'['sss']`。最后一步 `[0]` 只取第一个元素,因此返回 `''sss'`,但如果有这样的元素会返回 `a[4]` (2认同)

gec*_*cco 13

您可以创建自己的列表类:

class MyList(list):
    def get(self, index, default=None):
        return self[index] if len(self) > index else default
Run Code Online (Sandbox Code Playgroud)

你可以像这样使用它:

>>> l = MyList(['a', 'b', 'c'])
>>> l.get(1)
'b'
>>> l.get(9, 'no')
'no'
Run Code Online (Sandbox Code Playgroud)


Vla*_*ala 6

try:
    b = a[4]
except IndexError:
    b = 'sss'
Run Code Online (Sandbox Code Playgroud)

一种更干净的方法(仅当您使用字典时才有效):

b = a.get(4,"sss") # exact same thing as above
Run Code Online (Sandbox Code Playgroud)

这是您可能喜欢的另一种方式(同样,仅适用于听写):

b = a.setdefault(4,"sss") # if a[4] exists, returns that, otherwise sets a[4] to "sss" and returns "sss"
Run Code Online (Sandbox Code Playgroud)


Tho*_*mas 5

您还可以为这些情况定义一个小帮助函数:

def default(x, e, y):
    try:
        return x()
    except e:
        return y
Run Code Online (Sandbox Code Playgroud)

它返回函数的返回值x,除非它引发了类型的异常e; 在这种情况下,它返回值y.用法:

b = default(lambda: a[4], IndexError, 'sss')
Run Code Online (Sandbox Code Playgroud)

编辑:使它只捕获一种指定类型的异常.

仍然欢迎提出改进建议!

  • @Thomas:恕我直言,它不够优雅,而且除了`之外的所有捕捉都令人担忧 (2认同)
  • 邮件列表上有关于这样的构造的讨论:http://mail.python.org/pipermail/python-dev/2009-August/091039.html (2认同)

Pep*_*ijn 5

对于通常需要第一个元素的情况,您可以

next(iter([1, 2, 3]), None)
Run Code Online (Sandbox Code Playgroud)

我可能会在过滤列表后使用它来“打开”列表。

next((x for x in [1, 3, 5] if x % 2 == 0), None)
Run Code Online (Sandbox Code Playgroud)

要么

cur.execute("SELECT field FROM table")
next(cur.fetchone(), None)
Run Code Online (Sandbox Code Playgroud)