是的,我知道之前已经讨论过这个主题( 在这里 , 这里 , 这里 , 这里 ),可是据我所知,除一个解决方案外,全部解决方案在这样的列表上均失败: shell
L = [[[1, 2, 3], [4, 5]], 6]
所需的输出是 编程
[1, 2, 3, 4, 5, 6]
甚至更好的迭代器。 这个问题是我看到的惟一适用于任意嵌套的解决方案: app
def flatten(x): result = [] for el in x: if hasattr(el, "__iter__") and not isinstance(el, basestring): result.extend(flatten(el)) else: result.append(el) return result flatten(L)
这是最好的模型吗? 我有事吗 任何问题? 函数
使用递归和鸭子类型生成器(针对Python 3更新): 测试
def flatten(L): for item in L: try: yield from flatten(item) except TypeError: yield item list(flatten([[[1, 2, 3], [4, 5]], 6])) >>>[1, 2, 3, 4, 5, 6]
尝试建立一个能够平化Python中不规则列表的函数颇有趣,可是固然这就是Python的目的(使编程变得有趣)。 如下生成器在某些警告方面工做得很好: spa
def flatten(iterable): try: for item in iterable: yield from flatten(item) except TypeError: yield iterable
它将扁平化您可能但愿单独保留的数据类型(例如bytearray
, bytes
和str
对象)。 此外,代码还依赖于如下事实:从不可迭代的对象请求迭代器会引起TypeError
。 code
>>> L = [[[1, 2, 3], [4, 5]], 6] >>> def flatten(iterable): try: for item in iterable: yield from flatten(item) except TypeError: yield iterable >>> list(flatten(L)) [1, 2, 3, 4, 5, 6] >>>
编辑: 对象
我不一样意之前的实现。 问题在于您不该该将没法迭代的东西弄平。 这使人困惑,并给人以错误的印象。 递归
>>> list(flatten(123)) [123] >>>
如下生成器与第一个生成器几乎相同,可是不存在试图展平不可迭代对象的问题。 当给它一个不适当的参数时,它会像人们指望的那样失败。 get
def flatten(iterable): for item in iterable: try: yield from flatten(item) except TypeError: yield item
使用提供的列表对生成器进行测试能够正常工做。 可是,新代码在给它一个不可迭代的对象时将引起TypeError
。 下面显示了新行为的示例。
>>> L = [[[1, 2, 3], [4, 5]], 6] >>> list(flatten(L)) [1, 2, 3, 4, 5, 6] >>> list(flatten(123)) Traceback (most recent call last): File "<pyshell#32>", line 1, in <module> list(flatten(123)) File "<pyshell#27>", line 2, in flatten for item in iterable: TypeError: 'int' object is not iterable >>>
这里的compiler.ast.flatten
在2.7.5的实现:
def flatten(seq): l = [] for elt in seq: t = type(elt) if t is tuple or t is list: for elt2 in flatten(elt): l.append(elt2) else: l.append(elt) return l
有更好,更快的方法(若是您已经到达这里,您已经看到了它们)
另请注意:
自2.6版起弃用:编译器软件包已在Python 3中删除。
这是一个简单的函数,能够平铺任意深度的列表。 没有递归,以免堆栈溢出。
from copy import deepcopy def flatten_list(nested_list): """Flatten an arbitrarily nested list, without recursion (to avoid stack overflows). Returns a new list, the original list is unchanged. >> list(flatten_list([1, 2, 3, [4], [], [[[[[[[[[5]]]]]]]]]])) [1, 2, 3, 4, 5] >> list(flatten_list([[1, 2], 3])) [1, 2, 3] """ nested_list = deepcopy(nested_list) while nested_list: sublist = nested_list.pop(0) if isinstance(sublist, list): nested_list = sublist + nested_list else: yield sublist
个人解决方案:
import collections def flatten(x): if isinstance(x, collections.Iterable): return [a for i in x for a in flatten(i)] else: return [x]
更加简洁,但几乎相同。