【发布时间】: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
【问题讨论】:
标签: python list indexing integer
如果我有这个列表列表:
[[1,2,3,4],[5,6,7,8,9,10],[11,12,13]]
我怎样才能根据给定的值找到子列表本身的索引?
例如:
如果我的值为 2,则返回的索引为 0
如果我的值为 9,则返回的索引将为 1
如果我的值为 11,则索引为 2
【问题讨论】:
标签: python list indexing integer
只需使用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))
如果您想要所有索引,或者如果您只想要 first 出现,则使用 @jrd1 演示的 list-comp,然后:
next((idx for idx, val in enumerate(your_list) if 2 in val), None)
我们在这里使用None 作为默认值,而不是在任何子列表中都找不到该值的情况下引发StopIteration。如果您希望引发异常,请删除默认值。
【讨论】:
如果您有很多查询和/或动态列表,那么您最好制作一张地图。特别是一个 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)相比,它看起来很糟糕。
这是一个(虽然效率低,但简洁的)递归解决方案:
def get_index(lst, num, index=0):
if num in lst[index]:
return index
else:
return get_index(lst, num, index + 1)
【讨论】: