有没有一种实用的方法可以做到这一点?

发布于 2024-08-26 02:14:57 字数 221 浏览 8 评论 0原文

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

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

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

When I don't know how deeply the lists will nest, this is the only way I can think to do this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

宛菡 2024-09-02 02:14:57
  1. 您应该避免在 Python 中进行类型检查。在这种情况下,这意味着避免按类型区分的任意嵌套结构。您可以构建自己的节点类型,可以通过类型检查以外的方法遍历该节点类型,例如查看特定属性。

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

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

  4. 我想还有一个更实用的方法。属性将是惰性评估。您可以这样实现

    def flatten(toFlatten):
        对于 toFlatten 中的项目:
            if isinstance(item, list): # Ewww,打字检查
                for subitem in flatten(item): # 他们正在考虑添加 
                    yield subitem #“yield from”到语言
                                              # 给出这个模式语法
            别的:
                产量项
    
  5. 递归在Python中非常有限(至少在其所有主要实现中),并且通常应该避免任意深度。很有可能重写此代码(以及所有递归代码)以使用迭代,这将使其更具可扩展性(并且功能较少,这在 Python 中是一件好事,但它并不特别适合 FP。)

  1. You should avoid typechecking in Python. In this case, this means avoiding arbitrarily-nested structures where you distinguish by type. You can build your own node type which you can traverse by methods other than typechecking, like looking at a specific attribute.

  2. For flattening one level or exactly n levels, look at itertools.chain.from_iterable.

  3. I don't know what you mean by "functional". This code is pretty functional: it uses recursion (not to its credit!) and it doesn't mutate its argument. (Strictly speaking, it does use mutable state for building a list, but that is just how you do it in Python.

  4. I suppose one more functional attribute would be lazy evaluation. You could implement this thusly

    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. Recursion is very limited in Python (at least, in all its major implementations) and should generally be avoided for arbitrary depth. It is quite possible to rewrite this (and all recursive code) to use iteration, which will make this more scalable (and less functional, which is a good thing in Python, which is not especially suited for FP.)

叫思念不要吵 2024-09-02 02:14:57

这个答案解释了为什么您不想在 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!

这种二次行为是完全可以避免的:原始解决方案(以及任意数量的其他解决方案)不会形成这些中间复制步骤。

This answer explains why you do not want to use reduce for this in Python.

Consider the snippet

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

What does this have to do?

[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!

This quadratic behavior is completely avoidable: the original solution (and any number of other solutions) does not form these intermediate copying steps.

呆萌少年 2024-09-02 02:14:57

itertools 的文档下,有一个 flatten()功能

Under the doc for itertools, there's a flatten() function

荭秂 2024-09-02 02:14:57

这是另一种选择(尽管可能有比类型检查更干净的东西,比如测试某些东西是否可迭代,因此不是“原子”):

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

它基于类似方案的东西。

Here's another option (though there may be something cleaner than type-checking, like testing if something is iterable and hence not an "atom"):

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

It's based on something scheme-like.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文