嵌套列表中元素的索引
Index of an element in a nested list
这几天我一直在努力锻炼。
给出的是以下嵌套列表:
[1, [5, 62, 6], 4, [99, [100, 200, 600, [1000, [2000]]]], [74, 41, 16], 7, [8], [[[400]]]]
还有这个函数体:
def find_element(liste, find, index = 0):
我必须在嵌套列表中找到一个元素,函数应该 return 找到的元素的确切索引,例如 [1,0] 表示 5 或 [3, 1, 3, 1 , 0] 为 2000。
该函数必须是递归的。
我的问题是如果元素不在列表中,函数必须 return 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
我尝试了第二个函数,当列表为空时 returns false 或如果索引为 0 且 indexList 为空时的 if 条件,但我得到的只是 RecursionError 或 TypeError。
您可以对生成器使用递归:
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]
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
,但在到达该点之前递归搜索所有子列表。此外,您必须检查您的列表条目本身是否是一个列表,但这只是一个类比,即一棵树可以具有指向其他节点的节点和不指向其他节点的节点(叶节点或普通旧数字)在你的情况下)。
我同意生成器非常适合这个问题。我会将程序逻辑分成两个单独的函数,dfs
和 find_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
这几天我一直在努力锻炼。 给出的是以下嵌套列表:
[1, [5, 62, 6], 4, [99, [100, 200, 600, [1000, [2000]]]], [74, 41, 16], 7, [8], [[[400]]]]
还有这个函数体:
def find_element(liste, find, index = 0):
我必须在嵌套列表中找到一个元素,函数应该 return 找到的元素的确切索引,例如 [1,0] 表示 5 或 [3, 1, 3, 1 , 0] 为 2000。 该函数必须是递归的。
我的问题是如果元素不在列表中,函数必须 return 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
我尝试了第二个函数,当列表为空时 returns false 或如果索引为 0 且 indexList 为空时的 if 条件,但我得到的只是 RecursionError 或 TypeError。
您可以对生成器使用递归:
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]
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
,但在到达该点之前递归搜索所有子列表。此外,您必须检查您的列表条目本身是否是一个列表,但这只是一个类比,即一棵树可以具有指向其他节点的节点和不指向其他节点的节点(叶节点或普通旧数字)在你的情况下)。
我同意生成器非常适合这个问题。我会将程序逻辑分成两个单独的函数,dfs
和 find_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