Python正确的深度反转功能?

时间:2017-09-14 23:55:24

标签: python

函数deepReverse应该返回一个完全反转的列表,其中的所有列表也会反转,但它只返回L(列表)的最后一个元素。我不知道如何解决这个问题,以便继续递归原始列表L.

正在做:

deepReverse([1, [2, 3], 4, [5, 6]]) -> [6, 5]

deepReverse([1, [2, 3], 4, [5, 6]]) -> [6, 5]

应该这样做:

deepReverse([1, [2, 3], 4, [5, 6]]) -> [[6, 5], 4, [3, 2], 1]

deepReverse([1, [2, [3, 4], [5, [6, 7], 8]]]) -> [[[8, [7, 6], 5], [4, 3], 2], 1]

当前代码:

def deepReverse(L):
    ''' Returns reversed list with all lists contained in it also reversed '''
    def deepReverse_helper(L, newlst):
        if L == []:
            return newlst
        if isinstance(L[-1], list):
            # element in L is a list
            return deepReverse_helper(L[-1], [])
        else:
            # element in L is not a list
            return deepReverse_helper(L[:-1], newlst + [L[-1]])
    return deepReverse_helper(L, [])

3 个答案:

答案 0 :(得分:1)

我不明白为什么它比必要的复杂,你不能尝试像这样的单行吗?

def deep_reverse(L):
    return [deep_reverse(l) if type(l) is list else l for l in reversed(L)]

>>> deep_reverse([1, [2, 3], 4, [5, 6]])
[[6, 5], 4, [3, 2], 1]

答案 1 :(得分:1)

你遇到的问题是你为了两个不同的目的而递归。首先,如果找到内部列表,则会递归以反转内部列表。其次,您正在递归代替迭代主列表。您可能需要在对辅助函数的单次调用中执行两者

我是这样做的:

def deep_reverse(L):
    def deep_reverse_helper(L, result):
        if not L:
            return result   # base case
        first, *rest = L
        if isinstance(first, list):
            first = deep_reverse_helper(first, [])   # first recursion (not always needed)
        result.append(first)
        return deep_reverse_helper(rest, result)   # second recursion
    return deep_reverse_helper(L, [])

我通过使用result而不是连接两个列表,避免每次运行append列表的额外不必要的副本。此代码仍为O(N**2),因为列表解包(first, *rest = L)需要O(N)次。如果您愿意,您可以使用切片执行相同的操作,但它具有完全相同的性能。

在外部列表中使用迭代(同时仍然递归以处理嵌套列表)在Python中会更自然。 itsneo's answer显示了一个非常好的方法。这是一个不太简洁的版本,如果您不熟悉Python,可能更容易理解:

def deep_reverse(L):
    result = []
    for value in reversed(L):
        if isinstance(value, list):
            value = deep_reverse(value)
        result.append(value)
    return result

答案 2 :(得分:0)

def deepReverse(L):
    def deepReverse_helper(L, newlst):
        if L == []:
            return newlst
        if isinstance(L[-1], list):
            # element in L is a list
            return deepReverse_helper(L[:-1], newlst + [deepReverse(L[-1])])
        else:
            # element in L is not a list
            return deepReverse_helper(L[:-1], newlst + [L[-1]])
    return deepReverse_helper(L, [])