60

是否有干净的方法来获取列表索引处的值,或者None索引在 Python 中是否超出或范围?

显而易见的方法是:

if len(the_list) > i:
    return the_list[i]
else:
    return None

但是,冗长会降低代码的可读性。有没有一种干净、简单、单线可以代替的方法?

4

7 回答 7

69

尝试:

try:
    return the_list[i]
except IndexError:
    return None

或者,一个班轮:

l[i] if i < len(l) else None

例子:

>>> l=list(range(5))
>>> i=6
>>> print(l[i] if i < len(l) else None)
None
>>> i=2
>>> print(l[i] if i < len(l) else None)
2
于 2012-08-29T20:59:16.560 回答
37

我发现列表切片对此很有用:

>>> x = [1, 2, 3]
>>> a = x [1:2]
>>> a
[2]
>>> b = x [4:5]
>>> b
[]

所以,如果你想要 x[i],总是访问 x[i:i+1]。如果存在,您将获得一个包含所需元素的列表。否则,您会得到一个空列表。

于 2016-01-22T06:18:21.040 回答
10

如果您正在处理小列表,则不需要添加 if 语句或类似的东西。一个简单的解决方案是将列表转换为字典。然后你可以使用dict.get

table = dict(enumerate(the_list))
return table.get(i)

您甚至可以设置另一个默认值None,而不是使用 的第二个参数dict.get。例如,用于在索引超出范围table.get(i, 'unknown')时返回。'unknown'

请注意,此方法不适用于负索引。

于 2018-04-11T11:43:31.783 回答
9

出于您的目的,如果不满足给定条件,您可以按默认返回的方式排除该else部分。None

def return_ele(x, i):
    if len(x) > i: return x[i]

结果

>>> x = [2,3,4]
>>> b = return_ele(x, 2)
>>> b
4
>>> b = return_ele(x, 5)
>>> b
>>> type(b)
<type 'NoneType'>
于 2012-08-29T21:07:04.077 回答
8
return the_list[i] if len(the_list) > i else None
于 2012-08-29T21:00:30.770 回答
7

结合切片和迭代

next(iter(the_list[i:i+1]), None)
于 2020-01-10T10:21:16.423 回答
2

1. 如果……否则……

l = [1, 2, 3, 4, 5]
for i, current in enumerate(l):
    following = l[i + 1] if i + 1 < len(l) else None
    print(current, following)
# 1 2
# 2 3
# 3 4
# 4 5
# 5 None

2. 试试……除了……

l = [1, 2, 3, 4, 5]
for i, current in enumerate(l):
    try:
        following = l[i + 1]
    except IndexError:
        following = None
    print(current, following)
# 1 2
# 2 3
# 3 4
# 4 5
# 5 None

3. 听写

适合小清单

l = [1, 2, 3, 4, 5]
dl = dict(enumerate(l))
for i, current in enumerate(l):
    following = dl.get(i + 1)
    print(current, following)
# 1 2
# 2 3
# 3 4
# 4 5
# 5 None

4.列表切片

l = [1, 2, 3, 4, 5]
for i, current in enumerate(l):
    following = next(iter(l[i + 1:i + 2]), None)
    print(current, following)
# 1 2
# 2 3
# 3 4
# 4 5
# 5 None

5. itertools.zip_longest

from itertools import zip_longest

l = [1, 2, 3, 4, 5]
for i, (current, following) in enumerate(zip_longest(l, l[1:])):
    print(current, following)
# 1 2
# 2 3
# 3 4
# 4 5
# 5 None

使用 Jupyter 的魔法命令%%timeit

在里面

from itertools import zip_longest

l = list(range(10000000))

结果

方法 消耗
如果别的... 2.62 秒
试试……除了…… 1.14 秒
听写 2.61 秒
列表切片 3.75 秒
itertools.zip_longest 1.14 秒
于 2021-06-24T08:44:10.837 回答