【问题标题】:Find a specific value in a large tree of sublists在子列表的大树中查找特定值
【发布时间】:2021-09-17 09:54:26
【问题描述】:

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

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"]]]))

编辑我才意识到这段代码有多糟糕

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

但是当我运行它时,我陷入了无限循环 谁能告诉我出了什么问题,也许可以给我一些真正工作一次的代码。

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

【问题讨论】:

  • @BhagyeshDudhediya 这些似乎只适用于列表列表,不适用于任意/不规则嵌套。
  • “也许给我一些代码,实际上可以一次工作”哦,对不起,您对我们的免费编码支持不满意吗?
  • 不,我的意思是我的代码
  • 因为我的从来不工作

标签: python list sublist


【解决方案1】:

使用递归函数:

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 大大改进了

【讨论】:

  • 您应该将其更改为 yield from find(...)yield idx + [j] 以使其更有用,以便仅查找 next 或所有此类索引元组。
  • @tobias_k。感谢这个改进的代码。我真的非常感谢你。
  • 不要将 [] 作为参数传递,而是将 def locate_value(c, chrs, idx): 更改为 def locate_value(c, chrs, idx=[]):。这将更加pythonic。
  • 我用两种解决方案更新了我的答案。
【解决方案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 对象本身就是可迭代对象,因此递归地保持迭代它们的元素(又是字符串)永远不会结束。

【讨论】:

  • 不错的答案,但另一个较短。
  • 这取决于您的喜好。与难以理解的简短答案相比,有些人更喜欢简单易读的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-02
  • 2017-11-29
  • 2015-05-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-05
相关资源
最近更新 更多