以递归方式展平 Python 中的不规则列表列表

joh*_*ith 1 python python-2.7

我搜索并发现具有相同标题的问题也是(这里 这里 这里 这里 这里),但我不是在问那个。我遇到了这个问题:

编写一个函数来展平一个列表。该列表包含其他列表、字符串或整数。

而我的代码是

t=[]
def flatten(aList):
    for i in aList:
        if type(i) !=list:
             t.append(i)
        else:
             flatten(i)

    return t     
Run Code Online (Sandbox Code Playgroud)

但是当我检查测试用例的代码时:

  1. flatten([[1], [1]]):检查器告诉我输出是[1, 1, 1, 1]但在 codeskulptor 中我得到正确的输出是[1, 1] .
  2. flatten([[[1]], [[[5]]]]):检查器告诉输出是[1, 1, 1, 1, 1, 2, 3, 3, 2, 1, 0, 4, 5, 6, 7, 1, 5]但在 codeskulptor 中告诉[1, 5]

许多测试用例都存在这个问题。然后我在 python 导师中检查了我的代码,发现在每次t返回列表时执行 if 语句之后,最后当函数停止时它返回最后编辑的列表t

我该如何解决这个问题,请帮我解决这个问题,是的,我是 Python 新手,对 itertools、lambda 函数用法、生成器等一无所知,所以请在我能理解的上下文中告诉我。

Mar*_*ers 5

您的代码依赖于全局;如果检查器两次调用您的函数,它会收到比预期更长的列表:

>>> t = []
>>> def flatten(aList):
...     for i in aList:
...         if type(i) !=list:
...              t.append(i)
...         else:
...              flatten(i)
...     return t
...
>>> flatten([1, 1])
[1, 1]
>>> flatten([1, 1])
[1, 1, 1, 1]
>>> t  # your global, still holding all those values:
[1, 1, 1, 1]
Run Code Online (Sandbox Code Playgroud)

不要使用全局变量。使用本地列表,并使用递归调用的结果扩展它:

def flatten(aList):
    t = []
    for i in aList:
        if not isinstance(i, list):
             t.append(i)
        else:
             t.extend(flatten(i))
    return t
Run Code Online (Sandbox Code Playgroud)

请注意,我切换到使用isinstance()来测试类型。此版本不会受到共享状态泄漏到下一次调用的影响:

>>> def flatten(aList):
...     t = []
...     for i in aList:
...         if not isinstance(i, list):
...              t.append(i)
...         else:
...              t.extend(flatten(i))
...     return t
...
>>> flatten([1, 1])
[1, 1]
>>> flatten([1, 1])
[1, 1]
>>> flatten([[[1]], [[[5]]]])
[1, 5]
>>> flatten([1, 1, [42, 81]])
[1, 1, 42, 81]
Run Code Online (Sandbox Code Playgroud)