在Python中,如何返回任意嵌套元素的索引列表?

4

假设我有一个列表:

>>> nested=[[1, 2], [3, [4]]]

我正在尝试编写一个函数,当我查找数字4时,它将返回[1,1,0]。如果在列表中没有指定的元素,则返回空列表[]

Nested 可以有任何结构,因此我认为一些递归函数最好,但我很难控制其深度和广度。

以下代码不是可工作的代码,但基本上是我考虑的思路:

def locate(x,element,loc=[0],counter=0):
    for c,i in enumerate(x):
        if isinstance(i,list):
            locate(i,loc+[0],counter+1)
        else:
            loc[counter]=c
            if i==element: return loc

函数调用应该是这个样子的:
>>> locate(nested,4)
[1,1,0]

递归函数可能不是最佳解决方案,但这只是我的尝试。


2
你目前的解决方案有什么问题?除了在递归时没有返回之外,还使用了默认可变参数。 - Morgan Thrapp
1
返回定位 (i, loc + [0], counter + 1) - Joran Beasley
1
如果有多个匹配项怎么办? - Andras Deak -- Слава Україні
1
@AndrasDeak 返回第一个实例将保持与列表索引方法类似的功能。 - LMc
3个回答

6
你可以考虑使用一种树形数据结构,不过以下是在当前的数据结构中的例子:
from collections import Iterable

def flatten(collection, depth=()):
    for i, element in enumerate(collection):
        if isinstance(element, Iterable) and not isinstance(element, str):
            yield from flatten(element, depth=depth + (i,))
        else:
            yield element, depth + (i,)

def locate(nested, element):
    for v, indices in flatten(nested):
        if v == element:
            return indices

2
def nested_find(l, e):
    for i, x in enumerate(l):
        if isinstance(x, list):
            t = nested_find(x, e)
            if t:
                return [i] + t
        elif x == e:
            return [i]

如果e不在l中,则返回None

1
请注意,(x, list); 后面有一个分号。 - LMc
您介意提供更详细的解释,说明这是如何工作的吗? - LMc
@LMc 当然可以。这个程序遍历了列表的每一个元素,如果该元素本身是一个列表,则在该列表上调用自身。如果该元素等于我们要查找的内容,则返回一个包含其在最近列表中索引的列表。然后,当我们退出递归调用时,我们添加包含我们要查找内容的列表的索引。如果在列表中没有找到目标元素,则在没有返回语句的情况下到达结尾,因此返回 None - Patrick Haugh

2

如果未找到该元素,则以下代码返回None,否则返回所需的输出:

   def locate(lst,ele):
        return  _locate(lst,ele,[])

    def _locate(lst,ele,res):
        for i,x in enumerate(lst):
            if isinstance(x,list):
                retVal = locate(x,ele,res+[i])
                if retVal is not None:
                    return retVal
            elif x==ele:
                return res+[i]
        return None

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接