在列表中查找项的索引

5 投票
4 回答
6771 浏览
提问于 2025-04-18 17:53

如果我有这样一个列表的列表:

[[1,2,3,4],[5,6,7,8,9,10],[11,12,13]]

我该如何根据给定的值找到子列表的索引呢?

举个例子:

如果我的值是2,那么返回的索引就是0

如果我的值是9,那么返回的索引就是1

如果我的值是11,那么返回的索引就是2

4 个回答

1

这里有一个(虽然有点低效,但很简洁的)递归解决方案:

def get_index(lst, num, index=0):
    if num in lst[index]:
        return index
    else:
        return get_index(lst, num, index + 1)
1

如果你有很多查询或者一个动态的列表列表,使用一个映射会更好。具体来说,就是使用一个值到集合的映射。在这个映射中,你把某个值对应到一个包含这个值的索引集合(子列表)。不过,这种方法最好是在列表不变的情况下使用。

比如说,对于这个例子 [[1,2,3,4],[5,6,7,8,9,10], [11,12,13], [1,2,3,4,5,6,7,8,9,10,11,12,13]

# Code for populating the map
map = collections.defaultdict(set)
index = 0
for i,v in enumerate(l):
    for _ in v:
        map[index].add(i)
        index += 1

# Result:
map = {
    1: {0,3},
    2: {0,3},
    3: {0,3},
    4: {0,3},
    5: {1,3},
    6: {1,3},
    7: {1,3},
    8: {1,3},
    9: {1,3},
    10:{1,3},
    11:{2,3},
    12:{2,3},
    13:{2,3}
}

你还可以把子列表当作区间来看(覆盖一系列的索引),这样可以通过建立一个区间树来实现O(log N)的查找和O(log N)的添加/删除子列表或元素。建立这个区间树需要O(L log L)的时间,其中L是子列表的数量。

4

如果你想要所有的索引,可以像@jrd1那样使用列表推导式;如果你只想要第一个出现的索引,可以使用下面的代码:

next((idx for idx, val in enumerate(your_list) if 2 in val), None)

这里我们用None作为默认值,这样在子列表中找不到值时就不会抛出StopIteration的错误。如果你希望在找不到值时抛出错误,可以去掉这个默认值。

11

只需使用 enumerate

l = [[1,2,3,4],[5,6,7,8,9,10],[11,12,13]]

# e.g.: find the index of the list containing 12
# This returns the first match (i.e. using index 0), if you want all matches
# simply remove the `[0]`
print [i for i, lst in enumerate(l) if 12 in lst][0] 

这会输出:

[2]

编辑:

@hlt的评论建议使用以下方法来提高效率:

next(i for i,v in enumerate(l) if 12 in v)

撰写回答