【问题标题】:Flatten an irregular list of lists in Python recursively以递归方式展平Python中的不规则列表列表
【发布时间】:2016-05-26 17:49:33
【问题描述】:

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

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

我的代码是

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

    return t     

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

  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 函数使用、生成器等一无所知。所以请在我能理解的上下文中告诉我。

【问题讨论】:

  • 您拥有的第二个链接提供了此功能的工作示例。
  • @Morgan Thrapp 该代码也不能解决我的真正问题
  • 仅用于代码样式:您应该使用isinstance() 而不是使用type(<var>) == type(<var>)
  • 为什么不呢?它适用于您的两个测试用例。如果这个问题实际上并没有问到你的问题,你应该问一个新问题。
  • @MorganThrapp:这个问题没有解释这个问题中的代码有什么问题。有时,如果 OP 正在尝试善意地尝试自行解决此问题,那么就某段不起作用的特定代码提出问题是可以。将其作为骗子关闭不会回答这个问题。

标签: python python-2.7


【解决方案1】:

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

>>> 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]

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

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

请注意,我切换到使用 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]

【讨论】:

  • @MorganThrapp:询问实现这一点的良好尝试是很好的。他们在问为什么他们的尝试没有成功。
  • @MorganThrapp:换句话说,找到一个好的骗子,答案是“不要使用全局变量,因为你的状态现在会泄漏到未来的调用中”,我也很乐意投票关闭。
  • @johnsmith:因为您不想丢弃递归调用产生的结果。递归函数调用与任何其他函数调用一样,如果该函数返回结果,请不要忽略它。
  • @johnsmith:试试看。将t.extend(flatten(i)) 调用替换为flatten(i),并使用flatten([1, [2, [3]]) 调用您的函数。会发生什么?
  • @johnsmith:或者做一些不同的事情:创建一系列相同的flattenN() 函数,其中N 是一个数字。 flatten1()flatten2() 等。每个函数 N 调用 N + 1。您可以根据需要扩展系列;对于具有 3 层嵌套的列表,您只需转到 flatten3()。您认为在flatten1() 中使用t.extend(flatten2(i)) 会发生什么,而仅使用flatten2(i) 会发生什么?
猜你喜欢
  • 1970-01-01
  • 2011-07-21
  • 1970-01-01
  • 2018-06-24
  • 2012-09-10
  • 1970-01-01
  • 2020-07-28
  • 2014-02-23
  • 1970-01-01
相关资源
最近更新 更多