在列表中查找项的索引
如果我有这样一个列表的列表:
[[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)