查找子子列表中的元素索引

时间:2014-01-21 15:56:03

标签: python list

我有一个如下所示的列表:

a = [[[0.0125, 6.6], [0.0125, 6.65], [0.0125, 6.7], [0.0125, 6.75], [0.0125, 6.8]], [[0.0185, 6.6], [0.0185, 6.65], [0.0185, 6.7], [0.0185, 6.75], [0.0185, 6.8]]]

ie:N子列表(这里只有两个)和每个子列表中的M子子列表(本例中为五个)。每个元素/子子列表由两个浮点数组成。

我需要找到给定元素的索引,比如[0.0185, 6.75]。在这种情况下,结果应为:[1, 3]

我不能在.index()上应用a运算符,因为该元素位于其中一个子列表中,因为我不知道它是哪一个我不能循环遍历应用该运算符的子列表,因为如果找不到该元素,它将导致错误。


添加

我在一个更大的数组(16个子列表和70个子子列表)中尝试了zhangxaochen ans DSM的答案,看看哪个更快,这就是我得到的:

DSM: 4.31537628174e-05
zhangxaochen: 0.00113296508789

由于DSM的回答速度要快26倍,我选择那个。谢谢你们!

4 个答案:

答案 0 :(得分:2)

一种方法是使用nextenumerate

>>> a = [[[0.0125, 6.6], [0.0125, 6.65], [0.0125, 6.7], [0.0125, 6.75], [0.0125, 6.8]], [[0.0185, 6.6], [0.0185, 6.65], [0.0185, 6.7], [0.0185, 6.75], [0.0185, 6.8]]]
>>> search_for = [0.0185, 6.75]
>>> print next(((i,j) for i,x in enumerate(a) for j,y in enumerate(x) 
...             if y == search_for), None)
(1, 3)
>>> search_for = [0.0185, 99]
>>> print next(((i,j) for i,x in enumerate(a) for j,y in enumerate(x) 
...             if y == search_for), None)
None

但是,由于测试浮点数的相等性可能过于敏感,因此您可能希望将y == search_for替换为is_close(y, search_for)函数,该函数允许对错误进行一些容忍。使用is in.index的方法无法真正解决这个问题。

答案 1 :(得分:2)

我想使用numpy来执行此操作:

In [93]: from numpy import *
    ...: a = [[[0.0125, 6.6], [0.0125, 6.65], [0.0125, 6.7], [0.0125, 6.75], [0.0125, 6.8]], [[0.0185, 6.6], [0.0185, 6.65], [0.0185, 6.7], [0.0185, 6.75], [0.0185, 6.8]]]
    ...: a=np.asarray(a)
    ...: needle=[0.0185, 6.75]
    ...: idx=nonzero(all(a==needle, axis=-1))
    ...: asarray(idx)[:,0]
    ...: 
Out[93]: array([1, 3])

我参考了这些帖子:

Python/NumPy first occurrence of subarray

https://github.com/numpy/numpy/issues/2269

通过这种方式,它可以处理深层嵌套案例,例如a=[[[[your data...],[...]]]]是4级嵌套,预期输出索引现在为(0,1,3)

In [95]: from numpy import *
    ...: a = [[[[0.0125, 6.6], [0.0125, 6.65], [0.0125, 6.7], [0.0125, 6.75], [0.0125, 6.8]], [[0.0185, 6.6], [0.0185, 6.65], [0.0185, 6.7], [0.0185, 6.75], [0.0185, 6.8]]]]
    ...: a=np.asarray(a)
    ...: needle=[0.0185, 6.75]
    ...: idx=nonzero(all(a==needle, axis=-1))
    ...: asarray(idx)[:,0]
Out[95]: array([0, 1, 3])

答案 2 :(得分:1)

使用next和生成器表达式:

search = [0.0185, 6.75]

gen = ((ix,iy) for ix,outer in enumerate(a) for iy,inner in enumerate(outer) if inner == search)

next(gen,'not found')
Out[27]: (1, 3)

如果生成器耗尽而没有找到结果,next将返回其第二个参数(在这种情况下为'not found',请使用您想要使用的任何内容)

如果上面的嵌套列表comp让你感到困惑,那么它在语法上等同于:

for ix,outer in enumerate(a):
    for iy,inner in enumerate(outer):
        if inner == search:
            yield (ix,iy)

答案 3 :(得分:0)

在致电in之前使用.index()测试会员资格。

def find(lst, needle):
    for i, sublist in enumerate(lst):
        if needle in sublist:
            return [i, sublist.index(needle)]

a = [[[0.0125, 6.6], [0.0125, 6.65], [0.0125, 6.7], [0.0125, 6.75], [0.0125, 6.8]], [[0.0185, 6.6], [0.0185, 6.65], [0.0185, 6.7], [0.0185, 6.75], [0.0185, 6.8]]]
element = [0.0185, 6.75]

print(find(a, element))

结果:

[1, 3]