简体   繁体   English

在Python中查找嵌套列表的索引

[英]Find the index of nested lists in Python

I am still fairly new to Python. 我对Python还是很陌生。 I have a list that includes numbers and lists of numbers: 我有一个包含数字和数字列表的列表:

list1 = [[3,3,2,2,1,1], 5, [2, 1], 2, [6,2,8]]

I have a function that will loop inside and determine if the item is a number or a list. 我有一个将在内部循环并确定该项目是数字还是列表的函数。 If a list is detected, it will loop inside the inner list, otherwise continue. 如果检测到列表,它将在内部列表内循环,否则继续。

def searchlist(ls):
    global list1
    for element in ls:
        if isinstance(element,list):
            searchlist(element)
        elif (element == 2):
            element += 3
            list1[?][?] = element

The code obviously doesn't work but I'm looking for a way I can get the values of [?] for the actual indices of 2 in the list. 该代码显然无法正常工作,但我正在寻找一种方法来获取列表中2的实际索引的[?]值。 So in the previous example, the following items will be replaced: 因此,在前面的示例中,以下项目将被替换:

list1[0][2], list1[0][3], list1[2][0], list1[3], and list1[4][1] list1 [0] [2],list1 [0] [3],list1 [2] [0],list1 [3]和list1 [4] [1]

I want this function to be able to change the value for the global variable (list1). 我希望此函数能够更改全局变量(list1)的值。 So for example after calling the function searchlist on the list list1 , the value of list1 should be: 因此,例如,在列表list1上调用函数searchlistlist1的值应为:

list1 = [[3,3,5,5,1,1], 5, [5, 1], 5, [6,5,8]]

And I want to use this function on any list in the future, so the sizes aren't constant. 而且我希望将来在任何列表上使用此函数,因此大小不是恒定的。

Since you already have a recursive function, you don't need to index the top-level nested list from the top, you just need to index the current ls parameter. 由于您已经具有递归功能,因此您无需从顶部开始对顶级嵌套列表进行索引,只需索引当前的ls参数即可。

For example, on the first match, ls is the same list as list1[0] , so ls[2] = … does the same thing as list1[0][2] = … . 例如,在第一个匹配, ls是相同的列表作为list1[0]所以ls[2] = …做同样的事情作为list1[0][2] = …

So: 所以:

def searchlist(ls):
    for i, element in enumerate(ls):
        if isinstance(element,list):
            searchlist(element)
        elif (element == 2):
            element += 3
            ls[i] = element

If you really did want to get a whole sequence of indexes, you'd need to build that up recursively, and then apply it either recursively or in a loop. 如果确实要获取整个索引序列,则需要以递归方式建立索引,然后以递归方式或以循环方式应用它。 Something like this: 像这样:

def searchlist(ls, *, _top=None, _indexes=()):
    if _top is None: _top = ls

    for i, element in enumerate(ls):
        if isinstance(element,list):
            searchlist(element, _top=_top, _indexes=_indexes + (i,))
        elif (element == 2):
            element += 3
            node = _top
            for index in _indexes:
                node = node[index]
            node[i] = element

To understand this, notice that a multiple-indexed list as an assignment target is a little weird: 要理解这一点,请注意将多索引列表作为分配目标有点奇怪:

lst[a][b][c] = d

What this actually does is something like this: 这实际上是这样的:

_tmp = lst[a][b]
_tmp.__setitem__(c, d)

In other words, the very last index is special, but all of the indices before it are treated as in a normal expression. 换句话说,最后一个索引是特殊的,但是之前的所有索引都被视为正则表达式。

So, that's why looping over node = node[index] for all indexes but the last one gives us the right thing to use with node[i] = … . 因此,这就是为什么对所有索引循环遍历node = node[index] ,但最后一个为我们提供了与node[i] = …一起使用的正确方法。

You don't need global . 您不需要global Here's a simple algorithm specific to the structure of your input: 这是特定于您的输入结构的简单算法:

list1 = [[3,3,2,2,1,1], 5, [2, 1], 2, [6,2,8]]

def changer(L, in_val, out_val):
    for idx, item in enumerate(L):
        if not isinstance(item, list):
            if item == in_val:
                L[idx] = out_val
        else:
            L[idx] = [i if i != in_val else out_val for i in item]
    return L

changer(list1, 2, 5)

[[3, 3, 5, 5, 1, 1], 5, [5, 1], 5, [6, 5, 8]]

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

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