您能否告诉我是否有选项可以获取嵌套深度未知的元素的索引,或者是否有一个变量可以指向此类元素的路径?
我正在解决一个非常需要“当场”进行更改的问题,尽管没有人禁止用更改后的结果替换原始源。
假设我们有一个列表:
lst = [
'el1',
['el2', 15, 'text'],
['el3', '2.6', ['el4', ['el5']]],
'el6'
]
从这个列表中,我们想要获取元素的路径'el5'以将其转换为例如元组。
我对 python 的基本了解表明,我们可以创建一个临时变量,并通过搜索底层列表,创建指向感兴趣元素的链接。
我可能是错的,但在这种情况下,我们将获得包含所需元素的本地片段的链接。但对于操作,我们需要使用索引的完整路径来引用源。否则,原始源中的转换将不会发生。
例如,当您沿着源移动时,您可以以索引列表的形式获取路径:
def find_elem(lst: list, elem: any) -> list[int] | None:
'''получаем путь до искомого элемента в виде списка индексов'''
for i, el in enumerate(lst):
if isinstance(el, (list, tuple)):
returned = find_elem(el, elem)
if returned != None: # проверяем был ли во вложенном списке искомый элемент
return [i, ] + returned
elif el == elem:
return [i, ]
return None # элемент в переданной коллекции не нашелся
print(find_elem(lst, 'el5')) # вернет путь виде списка [2, 2, 1, 0]
问题是如何将这个列表转换为
needed_elem = lst[2][2][1][0]
PS 我把这个函数写在膝盖上只是为了展示问题的本质。
UPD。我附上了应用算法的结果以及所需元素的源和本地化之旅。结果,原始来源仍保持其原始形式......
needed_elem = find_elem(lst, 'text') № [1, 2]
needed_addr = lst[1][2]
needed_addr = ['text', 'new text']
print(lst) # ['el1', ['el2', 15, 'text'], ['el3', '2.6', ['el4', ['el5']]], 'el6']
lst[1][2] = ['text', 'new text']
print(lst) # ['el1', ['el2', 15, ['text', 'new text']], ['el3', '2.6', ['el4', ['el5']]], 'el6']
从上面的例子可以看出,只有第二版的申诉才导致了变化。
创建一个新的列表列表,您将在其中递归地放置旧列表中的所有元素,并用所需的元素替换所需的元素。这是列表列表的示例,您需要使用元组来完成它:
更新
如果您只是想知道如何获取给定嵌套索引列表的元素,那么它的实现如下:
但是,我不知道以这种方式更改列表项的值的合法方法。
更新2
正如这里正确建议的那样,获取对象就足够了 - 具有所需元素和该元素索引的最嵌套列表,然后就可以更改值:
当您从列表(包括深度嵌套列表)中获取元素时,您确实获得了引用,但不是指向嵌套列表中的位置,而是指向值本身。此链接无法替换列表中的元素。你只能改变一个对象(如果它是可变的),那么它的改变将反映在原始结构中。
要更改嵌套列表内的值,您已经需要列表本身(元素所在的嵌套列表)和其中的索引,即有条件地需要两个“坐标”。然后就可以通过替换找到的索引处的值来改变列表:
结论:
该问题已经有两个正确答案。除了解决问题的可能设计之外,我几乎没有什么可补充的。
有两种解决方案。第一个很简单。第二个是语法糖。
一个简单的解决方案
locate(list_, value)value- 返回列表中所有出现的值的生成器list_。列表本身及其所有子列表都是递归查看的。replace_first(list_, old, new)将第一个值old(如果有)替换为new。replace_all(list_, old, new)将所有值替换old为new.多索引解决方案
该类
NestedList包装一个列表并提供如下语法: