在python中查找嵌套项的索引

时间:2014-06-25 22:13:54

标签: python arrays indexing tuples

我一直在使用一些相对复杂的数组,例如:

array = [ "1", 2, ["4", "5", ("a", "b")], ("c", "d")]

我正在寻找一种方法来查找项目并检索是“索引”(是否可以引用项目的位置,如“a” - 在元组内部作为索引与数组处于同一级别?)

现在我的第一个想法是使用类似简单帮助函数的东西,例如:

def myindex(nestedlist, item):
    for i in nestedlist:
        if item in i:
         index = []
         index.append(i)
         index.append(i.index(item))
         return index

但我相信你可以猜测这样的功能不会有多大好处,特别是因为我事先并不知道数组可能有多少级别,以及每个级别可能包含的内容(就数据而言)类型/结构)

任何正确方向的提示都会非常感激!

3 个答案:

答案 0 :(得分:6)

你想要的是:

def myindex(lst, target):
    for index, item in enumerate(lst):
        if item == target:
            return [index]
        if isinstance(item, (list, tuple)):
            path = myindex(item, target)
            if path:
                return [index] + path
    return []

作为递归,这将处理任意深度的嵌套(直到递归限制)。

对于您的示例array,我得到:

>>> myindex(array, "a")
[2, 2, 0]

正如Adam在评论中提到的那样,明确地检查实例类型并不是非常Pythonic。 duck-typed"easier to ask for forgiveness than permission"替代方案是:

def myindex(lst, target):
    for index, item in enumerate(lst):
        if item == target:
            return [index]
        if isinstance(item, str): # or 'basestring' in 2.x
            return []
        try:
            path = myindex(item, target)
        except TypeError:
            pass
        else:
            if path:
                return [index] + path
    return []

字符串的特定处理是必要的,因为即使是空字符串也可以迭代,导致无休止的递归。

答案 1 :(得分:1)

array = [“1”,2,[“4”,“5”,(“a”,“b”)],(“c”,“d”)]

def find_index(array, item, index=None):
    if not index:
        index = []
    try:
        i = array.index(item)
    except:
        for new_array in array:
           if hasattr(new_array, '__iter__'):
               i = find_index(new_array, item, index+[array.index(new_array)])
               if i:
                   return i
    else:
        return index + [i]
    return None

这给出了:

>>> find_index(array, 1)
>>> find_index(array, "1")
[0]
>>> find_index(array, 2)
[1]
>>> find_index(array, "4")
[2, 0]

答案 2 :(得分:0)

我参加派对有点晚了,但是我花了几分钟时间,所以我觉得它应该被贴出去了:)

def getindex(container, target, chain=None):
    if chain is None: chain = list()
    for idx, item in enumerate(container):
        if item == target:
            return chain + [idx]
        if isinstance(item, collections.Iterable) and not isinstance(item, str):
            # this should be ... not isinstance(item, basestring) in python2.x
            result = getindex(item, target, chain + [idx])
            if result:
                return result
    return None