列表中的递归

Recursion in lists

def obsah(myList):
    def recursion(myList,deep=1,result=(None)):
        if type(myList) == list:
            for i in range(len(myList)):
                if type(myList[i]) == list:
                    deep+=1
                    recursion(myList[i],deep,result)
                else:
                    result = (deep,myList[i])
                    break
        else:
            result = (0,myList)
        return result
    return recursion(myList)

这个函数应该return递归的部门和列表中最后一个元素的值作为元组:

 obsah(['a'])
(1, 'a')
>>> obsah([[123]])
(2, 123)
>>> obsah([[[[[(3,7)]]]]])
(5, (3, 7))
>>> obsah(3.14)
(0, 3.14)
>>> obsah([[[1],2]])
(1, None)

instead the outputs are:

(1, 'a')
None
None
(0, 3.14)
None

经过几次测试,我发现我的临时结果很好,但是,使用默认参数(none)递归了一次,问题在哪里?它不应该以 returns 结尾吗?

首先,题外话:

而不是这样写:

for i in range(len(myList)):
    myList[i]

这样写:

for element in myList:

或者,如有必要:

for i, element in enumerate(myList):

现在,您的代码...

当我们编写递归函数时,我们想非常明确地讨论两种情况。基本情况和递归情况。我们应该能够在我们的代码中将它们建模为那种风格非常明确

在您的代码中,您确实没有遵循该模型。我真的找不到基本案例。让我们谈谈基本情况:

  1. 如果传递给递归函数的对象不是list类型,那么我们return当前深度和传入的对象。
  2. 如果传递给递归函数的列表的长度不是1,那么我们return当前深度和None.

我们的递归案例是增加深度并将myList[0]传递给递归调用。

因此您的代码应该相当简单:

def obsah(myList):
    return recursion(myList)

def recursion(myList, depth=0):
    # Base Case
    if type(myList) != list:
        return (depth, myList)

    # Another Base Case:
    if len(myList) != 1:
        return (depth, None)

    # Iterative case
    return recursion(myList[0], depth+1)

print obsah(['a'])
print obsah([[123]])
print obsah([[[[[(3,7)]]]]])
print obsah(3.14)
print obsah([[[1],2]])

输出:

(1, 'a')
(2, 123)
(5, (3, 7))
(0, 3.14)
(1, None)

记住:

这里的关键是在开始编写实际代码之前写下基本情况和递归情况。

使用 while 循环的更简单的解决方案:

def obsah(nested):
    depth = 0
    while isinstance(nested, list) and len(nested) == 1:
        nested = nested[0]
        depth += 1
    return depth, None if isinstance(nested, list) else nested

print obsah(['a'])
print obsah([[123]])
print obsah([[[[[(3,7)]]]]])
print obsah(3.14)
print obsah([[[1],2]])

打印:

(1, 'a')
(2, 123)
(5, (3, 7))
(0, 3.14)
(1, None)

return中的这个大if纯粹是为了特殊情况,这告诉我方法或问题定义有问题。