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

时间:2018-07-17 18:43:39

标签: python list

我对Python还是很陌生。我有一个包含数字和数字列表的列表:

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

我有一个函数,该函数将在内部循环并确定该项目是数字还是列表。如果检测到列表,它将在内部列表内循环,否则继续。

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

代码显然不起作用,但是我正在寻找一种方法来获取列表中2的实际索引的[?]值。因此,在前面的示例中,以下项目将被替换:

  

列表1 [0] [2],列表1 [0] [3],列表1 [2] [0],列表1 [3]和列表1 [4] [1]

我希望此函数能够更改全局变量(list1)的值。因此,例如,在调用列表searchlist上的函数list1之后,list1的值应为:

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

而且我希望将来在任何列表上使用此功能,因此大小不是恒定的。

2 个答案:

答案 0 :(得分:3)

由于您已经具有递归函数,因此无需从顶部开始索引顶级嵌套列表,只需索引当前的ls参数即可。

例如,在第一个比赛中,lslist1[0]是相同的列表,因此ls[2] = …的作用与list1[0][2] = …相同。

所以:

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

如果您确实想获取整个索引序列,则需要递归地建立索引,然后递归或循环地应用它。像这样:

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

要了解这一点,请注意,将多索引列表作为分配目标有点奇怪:

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

这实际上是这样的:

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

换句话说,最后一个索引是特殊的,但是之前的所有索引都被视为正则表达式。

因此,这就是为什么为所有索引循环访问node = node[index]的原因,但最后一个索引为我们提供了与node[i] = …一起使用的正确选择。

答案 1 :(得分:1)

您不需要global。这是特定于您的输入结构的简单算法:

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