Python:将值添加到最内层右嵌套列表的末尾

4 投票
5 回答
555 浏览
提问于 2025-04-16 16:28

我想做的是,给定一个包含任意数量嵌套列表的列表,递归地深入到嵌套列表的最后一个值,直到达到最大深度,然后在那个列表中添加一个值。举个例子可能会更清楚:

>>> nested_list1 = [1, 2, 3, [4, 5, 6]]
>>> last_inner_append(nested_list1, 7)
[1, 2, 3, [4, 5, 6, 7]]

>>> nested_list2 = [1, 2, [3, 4], 5, 6]
>>> last_inner_append(nested_list2, 7)
[1, 2, [3, 4], 5, 6, 7]

下面的代码可以运行,但我觉得它有点复杂:

def add_to_inner_last(nested, item):
    nest_levels = [nested]
    try:
        nest_levels.append(nested[-1])
    except IndexError:                    # The empty list case
        nested.append(item)
        return
    while type(nest_levels[-1]) == list:
        try:
            nest_levels.append(nest_levels[-1][-1])
        except IndexError:                 # The empty inner list case
            nest_levels[-1].append(item)
            return
    nest_levels[-2].append(item)
    return

我喜欢它的一些地方:

  • 它能正常工作
  • 它处理了列表末尾是字符串的情况,以及空列表的情况

我不喜欢它的一些地方:

  • 我必须检查对象的类型,因为字符串也可以用索引访问
  • 索引系统感觉太神秘了——我明天可能就不理解了
  • 利用引用列表的特性来添加元素,影响所有引用,感觉有点过于聪明

我对它有一些一般性的问题:

  • 一开始我担心向 nest_levels 添加元素会浪费空间,但后来我意识到这可能只是一个引用,并没有创建新的对象,对吧?
  • 这段代码纯粹是产生副作用(它总是返回 None)。我需要担心这个吗?

基本上,虽然这段代码能工作(我想...),但我在想是否有更好的方法来实现这个。所谓更好,是指更清晰或更符合Python风格的方式。可能是更明确的递归?我在定义停止点或以不产生副作用的方式来实现这个时遇到了困难。

编辑:

为了明确,这个方法还需要处理:

>>> last_inner_append([1,[2,[3,[4]]]], 5)
[1,[2,[3,[4,5]]]]

以及:

>>> last_inner_append([1,[2,[3,[4,[]]]]], 5)
[1,[2,[3,[4,[5]]]]]

5 个回答

1

这是我的看法:

def last_inner_append(cont, el):
    if type(cont) == list:
        if not len(cont) or type(cont[-1]) != list:
            cont.append(el)
        else:
            last_inner_append(cont[-1], el)
  • 我觉得这个方法很好,很清晰,而且通过了你所有的测试。
  • 它也是纯粹的副作用;如果你想改变这个,我建议你采用BasicWolf的方法,创建一个“选择器”和一个“更新”函数,后者使用前者。
  • 这个递归的方式和Phil H的相同,但可以处理空列表。
  • 不过,我认为无论你用什么方法(比如用'type'或者检查'append'),都没有好的办法来避免这两个类型测试。
2

这个函数会返回最深层的内部列表:

def get_deepest_list(lst, depth = 0):
    deepest_list = lst
    max_depth = depth

    for li in lst:
        if type(li) == list:
            tmp_deepest_list, tmp_max_depth = get_deepest_list(li, depth + 1)
            if max_depth < tmp_max_depth: # change to <= to get the rightmost inner list
                max_depth = tmp_max_depth
                deepest_list = tmp_deepest_list

    return deepest_list, max_depth

然后可以这样使用它:

def add_to_deepest_inner(lst, item):
    inner_lst, depth = get_deepest_list(lst)
    inner_lst.append(item)
4

这样怎么样:

def last_inner_append(x, y):
    try:
        if isinstance(x[-1], list):
            last_inner_append(x[-1], y)
            return x
    except IndexError:
        pass
    x.append(y)
    return x

撰写回答