在列表列表中查找项目的索引
Posted
技术标签:
【中文标题】在列表列表中查找项目的索引【英文标题】:Finding the index of an item in a list of lists 【发布时间】:2014-10-13 10:18:49 【问题描述】:如果我有这个列表列表:
[[1,2,3,4],[5,6,7,8,9,10],[11,12,13]]
我怎样才能根据给定的值找到子列表本身的索引?
例如:
如果我的值为 2,则返回的索引为 0
如果我的值为 9,则返回的索引将为 1
如果我的值为 11,则索引为 2
【问题讨论】:
【参考方案1】:只需使用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's 评论建议使用以下更有效的行为:
next(i for i,v in enumerate(l) if 12 in v)
【讨论】:
这会找到所有的匹配项。您需要使用[0]
或(更有效)将事物转换为迭代器,然后使用next
提取第一个元素(即next(i for i,v in enumerate(l) if 12 in v)
)
@hlt:感谢您的评论。你说的很对!已更新。【参考方案2】:
如果您想要所有索引,或者如果您只想要 first 出现,则使用 @jrd1 演示的 list-comp,然后:
next((idx for idx, val in enumerate(your_list) if 2 in val), None)
我们在这里使用None
作为默认值,而不是在任何子列表中都找不到该值的情况下引发StopIteration
。如果您希望引发异常,请删除默认值。
【讨论】:
【参考方案3】:如果您有很多查询和/或动态列表,那么您最好制作一张地图。特别是一个 value:set 映射。您将值映射到包含该值的一组索引(子列表)。虽然如果列表没有改变,这效果最好。
[[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) 通过构建 interval tree 添加/删除子列表/元素。构建区间树需要 O(L log L),其中 L 是子列表的数量。
【讨论】:
这看起来不够优雅。这是有道理的,不要误会我的意思,但与next((idx for idx, val in enumerate(your_list) if 2 in val), None)
相比,它看起来很糟糕。
它只是看起来很丑,因为我只给出了我所想的结果。添加了 for 循环(我很想看到它作为单线完成)。还添加了关于使用区间树的注释。【参考方案4】:
这是一个(虽然效率低,但简洁的)递归解决方案:
def get_index(lst, num, index=0):
if num in lst[index]:
return index
else:
return get_index(lst, num, index + 1)
【讨论】:
以上是关于在列表列表中查找项目的索引的主要内容,如果未能解决你的问题,请参考以下文章