嵌套列表中元素的索引

时间:2020-10-10 22:51:32

标签: python recursion nested-lists

我正努力锻炼几天。 给出以下嵌套列表:

[1, [5, 62, 6], 4, [99, [100, 200, 600, [1000, [2000]]]], [74, 41, 16], 7, [8], [[[400]]]]

这个函数体:

def find_element(liste, find, index = 0):

我必须在嵌套列表中找到一个元素,该函数应该返回找到的元素的精确索引,例如[1,0]表示5或[3,1,3,1,0]表示2000。 该函数必须是递归的。

我的问题是,如果元素不在列表中,则该函数必须返回false。

这是我的代码:

def find_element(liste, find, index = 0):
    indexList = []

    if len(liste) == index:
        return indexList

    if liste[index] == find:
        indexList.append(index)
    else:
        if type(liste[index]) == list:
            indexList.extend(find_element(liste[index], find))
        if indexList:
            indexList.insert(0, index)
        else:
            indexList.extend(find_element(liste, find, index + 1))

    return indexList

我尝试了第二个函数,该函数在列表为空或索引条件为0并且indexList为空的if条件下返回false,但是我得到的只是RecursionError或TypeError。

3 个答案:

答案 0 :(得分:0)

您可以将递归与生成器一起使用:

def find_element(l, elem):
  def get_elem(d, c = []):
    for i, a in enumerate(d):
       if a == elem:
          yield c+[i]
       elif isinstance(a, list):
          yield from get_elem(a, c+[i])
  return False if not (r:=list(get_elem(l))) else r[0]

data = [1, [5, 62, 6], 4, [99, [100, 200, 600, [1000, [2000]]]], [74, 41, 16], 7, [8], [[[400]]]]
print(find_element(data, 2000))

输出:

[3, 1, 3, 1, 0]

答案 1 :(得分:0)

Ajax1234的答案有效,但是如果您需要更简单的方法,可能会更好:

def find_idx(input_list, elem):
  for i in range(len(input_list)):
    if isinstance(input_list[i], list):
      result = find_idx(input_list[i], elem)
      if result:
        return [i] + result
    elif input_list[i] == elem:
        return [i]

  return False

input_list = [1, [5, 62, 6], 4, [99, [100, 200, 600, [1000, [2000]]]], [74, 41, 16], 7, [8], [[[400]]]]

print(find_idx(input_list, 2000))
# Output: [3, 1, 3, 1, 0]  

 

这基本上是DFS(https://en.wikipedia.org/wiki/Depth-first_search)。如果您将数据结构视为树,则列表条目就是节点,因为它们本身可以包含其他列表,就像树中的节点可以指向其他节点一样。妙处在于,如果在方法的最后未找到任何内容,则返回False,但在到达该点之前递归搜索所有子列表。另外,您还必须检查列表条目本身是否为列表,但这仅类似于一个事实,即树可以有指向其他节点的节点,而没有指向其他节点的节点(叶节点或简单的旧数字)就您而言)。

答案 2 :(得分:0)

我同意生成器非常适合此问题。我将程序逻辑分为两个独立的函数dfsfind_element-

def dfs(ls, r = []):
  if isinstance(ls, list):
    for (i, v) in enumerate(ls):
      yield from dfs(v, [*r, i])
  else:
    yield (r, ls)

def find_element(ls, q):
  for (k, v) in dfs(ls):
    if v == q:
      return k
  return None
print(find_element(input, 5))
# [1, 0]

print(find_element(input, 2000))
# [3, 1, 3, 1, 0]

print(find_element(input, 999))
# None

或者您可以使用第四个参数r = []-

修复原始程序
def find_element(ls, q, i = 0, r = []):
  if i >= len(ls):
    return None
  elif isinstance(ls[i], list):
    return find_element(ls[i], q, 0, [*r, i]) \
      or find_element(ls, q, i + 1, r)
  elif ls[i] == q:
    return [*r, i]
  else:
    return find_element(ls, q, i + 1, r)
print(find_element(input, 5))
# [1, 0]

print(find_element(input, 2000))
# [3, 1, 3, 1, 0]

print(find_element(input, 999))
# None