使用递归反转列表中的列表

2 投票
5 回答
1404 浏览
提问于 2025-04-17 19:19
def is_list(p):
    return isinstance(p, list)

def deep_reverse(p):
    initial = []
    for v, e in enumerate(p):
        if is_list(e):
            #print p[v][::-1]
            initial.append(p[v][::-1])
            deep_reverse(e)
    return initial

p = [1, [2, 3, [4, [5, 6, [7, 8]]]]]
print deep_reverse(p)

我得到了 [[[4, [5, 6, [7, 8]]], 3, 2]],但我期待的结果至少是 [[[[6, 5, [8, 7]], 4], 3, 2]](我还没想明白怎么才能不丢掉最开始的那个列表 [1[...]])。

你可以看到,代码只反转了 [ [2, 3]],变成了 [[3, 2]]。我哪里出错了呢?我是不是没考虑到什么?

5 个回答

2

已经有很多不错的解决方案了,但也许这就是你想要的算法:

def is_list(p):
    return isinstance(p, list)

def deep_reverse(p):
    initial = p[::-1] # reverse this level
    for v, e in enumerate(initial): 
        if is_list(e): # for all the sublist in this level
            initial[v] = deep_reverse(e) # recursively call deep_reverse to reverse the sublist
    return initial

p = [1, [2, 3, [4, [5, 6, [7, 8]]]]]
print deep_reverse(p)
3

这里有一个更通用、更符合Python风格的答案,基于Pavel Anossov的内容,具体如下:

def deep_reversed(seq):
    return [deep_reversed(x) if (isinstance(x, collections.Sequence) and 
                                not isinstance(x, str)) else x 
            for x in reversed(seq)]

请注意,这个答案适用于Python 3.x,如果你在用Python 2.x,应该使用isinstance(x, basestring),这样才能支持Unicode字符串。

这个答案很好,因为它可以正确处理任何像序列一样的对象——无论是列表、元组,还是自定义的类。这意味着它的适用性更广。

补充:如果你想让它内部反转字符串:

def deep_reversed(seq):
    for x in reversed(seq):
        if isinstance(x, collections.Sequence):
            if isinstance(x, str):
                yield "".join(reversed(x))
            else:
                yield deep_reversed(x)
        else:
            yield x

同样,在2.x中,使用isinstance(x, basestring)

5

我会这样做:

def deep_reverse(p):
    return [deep_reverse(x) if isinstance(x, list) else x for x in p[::-1]]

p = [1, [2, 3, [4, [5, 6, [7, 8]]]]]
print deep_reverse(p)   #  [[[[[8, 7], 6, 5], 4], 3, 2], 1]

撰写回答