在大型子列表树中查找特定值

Find a specific value in a large tree of sublists

我有一些代码可以生成如下所示的列表:

chrs = [[["a",["b","c"]],["d","e"],"f"],["g",[["h","i"],"j"]]]

现在我需要在类似这样的列表中找到特定值。
我写了一些代码来做到这一点,但它似乎陷入了无限循环:

def locate_value(v,chrs):                       #
    checked=[[]]                                # Set up the values
    index_list=[]                               #
    inside=0                                    #
    cur=[0,0]                                   #
                                                #
    while True:                                 #
        if chrs[cur[0]] == v:                   # If found, end the loop and return the index_list
            return index_list                   #
                                                #
        if type(chrs[cur[0]]) != list:          # If the current is not a list, skip this one
            checked[inside].append(cur[0])      #
            index_list = []                     #
                                                #
        else:                                   #
            try:                                #
                if cur[0] in gone[inside]:      # If the current has been done before, skip it
                    cur[0] += 1                 #
                                                #
                else:                           # And if not, move 1 space deeper
                    checked.append([])          #
                    index_list.append(cur[0])   #
                    cur[1] = cur[0]             #
                    cur[0] = 0                  #
                    inside += 1                 #
                                                #
            except IndexError:                  # And if a sublist is fully checked, block it too
                checked[inside].append(cur[1])  #



print(locate_value("e",[[["a",["b","c"]],["d","e"],"f"],["g",[["h","i"],"j"]]]))

Editing me just realised how bad this code is

在这个例子中,函数 locate_value 应该 return [0, 1, 1],因为 list[0][1][1]"e"

但是当我运行这个的时候,我陷入了一个无限循环 任何人都可以告诉我哪里出了问题,也许可以给我一些实际上 有效 一次的代码。

这个列表是用户输入的,所以我不知道它有多深。
虽然仅 python-3 的解决方案很好,但我更喜欢支持 python-2 的解决方案。

以下将起作用:

def locate_value(v, chrs):
    if v == chrs:
        return []
    if not isinstance(chrs, list):
        raise IndexError
    for i, c in enumerate(chrs):
        try:
            return [i] + locate_value(v, c)
        except IndexError:
            pass
    raise IndexError


locate_value("e", [[["a",["b","c"]],["d","e"],"f"],["g",[["h","i"],"j"]]])
# [0, 1, 1]

请注意,str 对象本身就是可迭代对象,因此递归地不断迭代它们的元素(再次是字符串)将永远不会结束。

使用递归函数:

def locate_value(v, chrs, idx=[]):
    for j, i in enumerate(chrs):
        if isinstance(i, list):
            yield from find(v, i, idx + [j])
        elif i == v:
            yield idx + [j]

保留您原有签名功能的另一个版本:

def locate_value(v, chrs):
    for j, i in enumerate(chrs):
        if isinstance(i, list):
            yield from ([j, *idx] for idx in locate_value(v, i))
        elif i == v:
            yield [j]

输出:

>>> list(locate_value('e', chrs, []))
[[0, 1, 1]]

# case of multiple 'e'
# chrs = [[["a",["b","c"]],["d","e"],"f"],["g",[["h","e"],"j"]]]

>>> list(locate_value('e', chrs))
[[0, 1, 1], [1, 1, 0, 1]]

大大改进@tobias_k