def flattenList(toFlatten):
 final=[]
 for el in toFlatten:
  if isinstance(el, list):
   final.extend(flattenList(el))
  else:
   final.append(el)
 return final

当我不知道列表将嵌套多深时,这是我能想到的唯一方法。

有帮助吗?

解决方案

下面是另一种选择(虽然可以有除类型检查的东西清洁器,像测试,如果事情是可迭代,因此不是一个“原子”):

def flatten(lst):
    if not isinstance(lst,list):
        return [lst]
    else:
        return reduce(lambda x,y:x+y,[flatten(x) for x in lst],[])

这是基于什么方案,等等。

其他提示

  1. 您应该避免在 Python 中进行类型检查。在这种情况下,这意味着避免按类型区分的任意嵌套结构。您可以构建自己的节点类型,您可以通过方法遍历该节点类型 其他 与类型检查相比,例如查看特定属性。

  2. 要展平一层或恰好 n 层,请查看 itertools.chain.from_iterable.

  3. 我不知道你所说的“功能性”是什么意思。这段代码非常实用:它使用递归(这不是它的功劳!)并且它不会改变它的参数。(严格来说,它确实使用可变状态来构建列表,但这就是在 Python 中的做法。

  4. 我想另一个功能属性是惰性求值。你可以这样实现

    def flatten(toFlatten):
        for item in toFlatten:
            if isinstance(item, list): # Ewww, typchecking
                for subitem in flatten(item): # they are considering adding 
                    yield subitem             # "yield from" to the  language
                                              # to give this pattern syntax
            else:
                yield item
    
  5. 递归在 Python 中非常有限(至少在其所有主要实现中),并且通常应该避免任意深度。很有可能重写此代码(以及所有递归代码)以使用迭代,这将使其更具可扩展性(并且功能较少,这在 Python 中是一件好事,Python 并不特别适合 FP。)

这答案解释了为什么你不想在Python中使用reduce这一点。

考虑片段

reduce(operator.add, [[1], [2], [3], [4], [5]])

这是什么都做?

[1] + [2] => [1, 2]
[1, 2] + [3] => This makes a new list, having to go over 1, then 2, then 3. [1, 2, 3]
[1, 2, 3] + [4] => This has to copy the 1, 2, and 3 and then put 4 in the new list
[1, 2, 3, 4] + [5] => The length of stuff I have to copy gets bigger each time!

此二次行为是完全可以避免的:原溶液(及任何数目的其它解决方案)不形成这些中间复制步骤

根据该文档为 itertools 时,有一个flatten()功能

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top