简体   繁体   English

嵌套列表中元素的索引

[英]Index of an element in a nested list

I'm struggling with an exercise for a few days.我在锻炼中挣扎了几天。 Given was following nested list:鉴于以下嵌套列表:

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

And this function body:这个函数体:

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

I have to find an element in the nested list and the function should return the exact index of the found element, for example [1,0] for 5 or [3, 1, 3, 1, 0] for 2000. The function has to be recursive.我必须在嵌套列表中找到一个元素,该函数应该返回找到的元素的确切索引,例如 [1,0] 表示 5 或 [3, 1, 3, 1, 0] 表示 2000。该函数有是递归的。

My problem is the function has to return false if the element is not in the list.我的问题是如果元素不在列表中,函数必须返回 false。

This is my code:这是我的代码:

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

I tried a second function that returns false when the list is empty or an if condition if the index is 0 and the indexList is empty, but all I got were a RecursionError or a TypeError.我尝试了第二个函数,该函数在列表为空时返回 false,或者如果索引为 0 且 indexList 为空则返回 if 条件,但我得到的只是 RecursionError 或 TypeError。

You can use recursion with a generator:您可以将递归与生成器一起使用:

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

Output:输出:

[3, 1, 3, 1, 0]

Ajax1234's answer works, but if you need something a little more simple this may be better: 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]  

 

This is basically a DFS ( https://en.wikipedia.org/wiki/Depth-first_search ).这基本上是一个 DFS ( https://en.wikipedia.org/wiki/Depth-first_search )。 If you think of your data structure as a tree, your list entries are nodes since they themselves can contain other lists, just as a node in a tree can point to other nodes.如果您将数据结构视为一棵树,那么您的列表条目就是节点,因为它们本身可以包含其他列表,就像树中的节点可以指向其他节点一样。 The magic is in returning False if nothing was found at the very end of the method, but recursively searching all sublists before you get to that point.神奇之处在于,如果在方法的最后没有找到任何内容,则返回False ,但在到达该点之前递归搜索所有子列表。 Also, you have to check whether your list entry is itself a list, but this is just an analogy to the fact that a tree can have nodes that do point to other nodes, and nodes that do not (leaf nodes, or plain old numbers in your case).此外,您必须检查您的列表条目本身是否是一个列表,但这只是一个类比,即一棵树可以具有指向其他节点的节点和不指向其他节点的节点(叶节点或普通旧数字)在你的情况下)。

I agree generators are a nice fit for this problem.我同意生成器非常适合这个问题。 I would separate the program logic into two separate functions, dfs and find_element -我会将程序逻辑分成两个独立的函数, 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

Or you could fix your original program using a fourth parameter, r = [] -或者您可以使用第四个参数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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM