如何从列表列表中创建一个平面列表?

我有一个类似于[[1, 2, 3], [4, 5, 6], [7], [8, 9]]的列表。我如何将其展平以获得[1, 2, 3, 4, 5, 6, 7, 8, 9]


如果您的列表列表来自嵌套列表推导,则可以通过修复推导来更简单/直接地解决问题;请参阅python列表推导;压缩列表列表?

这里最流行的解决方案通常只展平嵌套列表的一个“级别”。请参阅展平不规则(任意嵌套)列表以获得完全展平深度嵌套结构的解决方案(通常是递归地)。

3715310 次浏览

使用#0,将累积列表xs添加到下一个列表ys

from functools import reducexss = [[1,2,3], [4,5,6], [7], [8,9]]out = reduce(lambda xs, ys: xs + ys, xss)

输出:

[1, 2, 3, 4, 5, 6, 7, 8, 9]

使用#0的更快方法:

from functools import reduceimport operatorxss = [[1,2,3], [4,5,6], [7], [8,9]]out = reduce(operator.concat, xss)

输出:

[1, 2, 3, 4, 5, 6, 7, 8, 9]

作者的说明:这是非常低效的。但是很有趣,因为偶数很棒。

>>> xss = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]>>> sum(xss, [])[1, 2, 3, 4, 5, 6, 7, 8, 9]

sum对可迭代xss的元素求和,并使用第二个参数作为求和的初始值[]。(默认初始值为0,不是列表。)

因为你是在对嵌套列表求和,所以你实际上得到了[1,3]+[2,4]作为sum([[1,3],[2,4]],[])的结果,它等于[1,3,2,4]

请注意,仅适用于列表的列表。对于列表的列表,您需要另一种解决方案。

给定一个列表l

flat_list = [item for sublist in l for item in sublist]

这意味着:

flat_list = []for sublist in l:for item in sublist:flat_list.append(item)

比目前发布的快捷方式更快。(l是要展平的列表。)

下面是对应的函数:

def flatten(l):return [item for sublist in l for item in sublist]

作为证据,您可以使用标准库中的timeit模块:

$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' '[item for sublist in l for item in sublist]'10000 loops, best of 3: 143 usec per loop$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'sum(l, [])'1000 loops, best of 3: 969 usec per loop$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'reduce(lambda x,y: x+y,l)'1000 loops, best of 3: 1.1 msec per loop

说明:当有L个子列表时,基于+的快捷方式(包括sum中的隐含用法)必然是O(L**2)-随着中间结果列表越来越长,每一步都会分配一个新的中间结果列表对象,并且必须复制上一个中间结果中的所有项目(以及最后添加的一些新项目)。因此,为了简单起见,并且没有实际的一般性损失,假设您有每个I项的L个子列表:第一个I项来回复制L-1次,第二个I项L-2次,依此类推;总副本数是I乘以x的总和从1到L排除,即I * (L**2)/2

列表理解只生成一个列表,一次,并复制每个项目(从其原始居住地到结果列表)一次。

你的函数不起作用的原因是延长就地扩展了一个数组并且不返回它。你仍然可以使用如下方式从lambda返回x:

reduce(lambda x,y: x.extend(y) or x, l)

注意:扩展在列表上比+更有效。

您可以使用#0

>>> import itertools>>> list2d = [[1,2,3], [4,5,6], [7], [8,9]]>>> merged = list(itertools.chain(*list2d))

或者您可以使用#0,它不需要使用*运算符解压缩列表:

>>> import itertools>>> list2d = [[1,2,3], [4,5,6], [7], [8,9]]>>> merged = list(itertools.chain.from_iterable(list2d))

这种方法可以说比[item for sublist in l for item in sublist]更具可读性,并且似乎也更快:

$ python3 -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99;import itertools' 'list(itertools.chain.from_iterable(l))'20000 loops, best of 5: 10.8 usec per loop$ python3 -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' '[item for sublist in l for item in sublist]'10000 loops, best of 5: 21.7 usec per loop$ python3 -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'sum(l, [])'1000 loops, best of 5: 258 usec per loop$ python3 -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99;from functools import reduce' 'reduce(lambda x,y: x+y,l)'1000 loops, best of 5: 292 usec per loop$ python3 --versionPython 3.7.5rc1

也可以使用NumPy的平面

import numpy as nplist(np.array(l).flat)

它仅在子列表具有相同维度时才有效。

如果你愿意为了更清晰的外观而放弃少量的速度,那么你可以使用numpy.concatenate().tolist()numpy.concatenate().ravel().tolist()

import numpy
l = [[1, 2, 3], [4, 5, 6], [7], [8, 9]] * 99
%timeit numpy.concatenate(l).ravel().tolist()1000 loops, best of 3: 313 µs per loop
%timeit numpy.concatenate(l).tolist()1000 loops, best of 3: 312 µs per loop
%timeit [item for sublist in l for item in sublist]1000 loops, best of 3: 31.5 µs per loop

您可以在留档numpy.concatenatenumpy.ravel中找到更多信息。

要展平深度嵌套的数据结构,请使用#01

>>> from iteration_utilities import deepflatten
>>> l = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]>>> list(deepflatten(l, depth=1))[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> l = [[1, 2, 3], [4, [5, 6]], 7, [8, 9]]>>> list(deepflatten(l))[1, 2, 3, 4, 5, 6, 7, 8, 9]

它是一个生成器,因此您需要将结果转换为list或显式迭代它。


为了只扁平化一个级别,如果每个项目本身都是可迭代的,你也可以使用#0,它本身只是#1周围的一个薄包装器:

>>> from iteration_utilities import flatten>>> l = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]>>> list(flatten(l))[1, 2, 3, 4, 5, 6, 7, 8, 9]

只是为了添加一些计时(基于Nico Schlömer的回答,不包括此答案中提供的函数):

在此处输入图片描述

这是一个对数-对数图,以适应跨越的大量值。对于定性推理:越低越好。

结果表明,如果迭代只包含几个内部迭代,那么sum将是最快的,但是对于长迭代,只有itertools.chain.from_iterableiteration_utilities.deepflatten或嵌套理解具有合理的性能,itertools.chain.from_iterable是最快的(正如Nico Schlömer已经注意到的那样)。

from itertools import chainfrom functools import reducefrom collections import Iterable  # or from collections.abc import Iterableimport operatorfrom iteration_utilities import deepflatten
def nested_list_comprehension(lsts):return [item for sublist in lsts for item in sublist]
def itertools_chain_from_iterable(lsts):return list(chain.from_iterable(lsts))
def pythons_sum(lsts):return sum(lsts, [])
def reduce_add(lsts):return reduce(lambda x, y: x + y, lsts)
def pylangs_flatten(lsts):return list(flatten(lsts))
def flatten(items):"""Yield items from any nested iterable; see REF."""for x in items:if isinstance(x, Iterable) and not isinstance(x, (str, bytes)):yield from flatten(x)else:yield x
def reduce_concat(lsts):return reduce(operator.concat, lsts)
def iteration_utilities_deepflatten(lsts):return list(deepflatten(lsts, depth=1))

from simple_benchmark import benchmark
b = benchmark([nested_list_comprehension, itertools_chain_from_iterable, pythons_sum, reduce_add,pylangs_flatten, reduce_concat, iteration_utilities_deepflatten],arguments={2**i: [[0]*5]*(2**i) for i in range(1, 13)},argument_name='number of inner lists')
b.plot()

1免责声明:我是该图书馆的作者

这是一个适用于数字字符串嵌套列表和混合容器的通用方法。这可以扁平化简单和复杂的容器(另见Demo)。

代码

from typing import Iterable#from collections import Iterable                            # < py38

def flatten(items):"""Yield items from any nested iterable; see Reference."""for x in items:if isinstance(x, Iterable) and not isinstance(x, (str, bytes)):for sub_x in flatten(x):yield sub_xelse:yield x

备注

  • 在Python 3中,yield from flatten(x)可以替换for sub_x in flatten(x): yield sub_x
  • 在Python 3.8中,抽象基类是从collection.abctyping模块的移动

Demo

simple = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]list(flatten(simple))# [1, 2, 3, 4, 5, 6, 7, 8, 9]
complicated = [[1, [2]], (3, 4, {5, 6}, 7), 8, "9"]              # numbers, strs, nested & mixedlist(flatten(complicated))# [1, 2, 3, 4, 5, 6, 7, 8, '9']

参考

  • 此解决方案是从Beazley,D.和B. Jones。食谱4.14,Python Cookbook第3版。,O'Reilly Media Inc.塞巴斯托波尔,加利福尼亚州:2013年。中的配方修改的
  • 找到了更早的so帖子,可能是原始演示。

考虑安装#0包。

> pip install more_itertools

它附带了#0的实现(来源,来自迭代工具食谱):

import more_itertools

lst = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]list(more_itertools.flatten(lst))# [1, 2, 3, 4, 5, 6, 7, 8, 9]

注意:正如文档中提到的flatten需要一个列表列表。


从2.4版开始,您可以使用#0来源,由abarnet贡献)展平更复杂的嵌套迭代。

lst = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]list(more_itertools.collapse(lst))# [1, 2, 3, 4, 5, 6, 7, 8, 9]
lst = [[1, 2, 3], [[4, 5, 6]], [[[7]]], 8, 9]              # complex nestinglist(more_itertools.collapse(lst))# [1, 2, 3, 4, 5, 6, 7, 8, 9]

以下对我来说似乎是最简单的:

>>> import numpy as np>>> l = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]>>> print(np.concatenate(l))[1 2 3 4 5 6 7 8 9]

我用灌流图测试了大多数建议的解决方案(我的一个宠物项目,本质上是围绕timeit的包装器),并发现

import functoolsimport operatorfunctools.reduce(operator.iconcat, a, [])

是最快的解决方案,当许多小列表和一些长列表连接时。(operator.iadd同样快。)

一个简单且可接受的变体是

out = []for sublist in a:out.extend(sublist)

如果子列表的数量很大,这比上面的建议要差一点。

在此处输入图片描述

在此处输入图片描述


重现情节的代码:

import functoolsimport itertoolsimport operator
import numpy as npimport perfplot

def forfor(a):return [item for sublist in a for item in sublist]

def sum_brackets(a):return sum(a, [])

def functools_reduce(a):return functools.reduce(operator.concat, a)

def functools_reduce_iconcat(a):return functools.reduce(operator.iconcat, a, [])

def itertools_chain(a):return list(itertools.chain.from_iterable(a))

def numpy_flat(a):return list(np.array(a).flat)

def numpy_concatenate(a):return list(np.concatenate(a))

def extend(a):out = []for sublist in a:out.extend(sublist)return out

b = perfplot.bench(setup=lambda n: [list(range(10))] * n,# setup=lambda n: [list(range(n))] * 10,kernels=[forfor,sum_brackets,functools_reduce,functools_reduce_iconcat,itertools_chain,numpy_flat,numpy_concatenate,extend,],n_range=[2 ** k for k in range(16)],xlabel="num lists (of length 10)",# xlabel="len lists (10 lists total)")b.save("out.png")b.show()
def flatten(alist):if alist == []:return []elif type(alist) is not list:return [alist]else:return flatten(alist[0]) + flatten(alist[1:])

另一种不寻常的方法适用于异质和同质整数列表:

from typing import List

def flatten(l: list) -> List[int]:"""Flatten an arbitrary deep nested list of lists of integers.
Examples:>>> flatten([1, 2, [1, [10]]])[1, 2, 1, 10]
Args:l: Union[l, Union[int, List[int]]
Returns:Flatted list of integer"""return [int(i.strip('[ ]')) for i in str(l).split(',')]

matplotlib.cbook.flatten()将适用于嵌套列表,即使它们比示例嵌套得更深。

import matplotlibl = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]print(list(matplotlib.cbook.flatten(l)))l2 = [[1, 2, 3], [4, 5, 6], [7], [8, [9, 10, [11, 12, [13]]]]]print(list(matplotlib.cbook.flatten(l2)))

结果:

[1, 2, 3, 4, 5, 6, 7, 8, 9][1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]

这是18倍快比下划线._.扁平化:

Average time over 1000 trials of matplotlib.cbook.flatten: 2.55e-05 secAverage time over 1000 trials of underscore._.flatten: 4.63e-04 sec(time for underscore._)/(time for matplotlib.cbook) = 18.1233394636

说明:下面适用于Python 3.3+,因为它使用#0six也是一个第三方包,尽管它很稳定。或者,您可以使用sys.version


obj = [[1, 2,], [3, 4], [5, 6]]的情况下,这里的所有解决方案都是好的,包括列表理解和itertools.chain.from_iterable

但是,考虑这个稍微复杂一点的案例:

>>> obj = [[1, 2, 3], [4, 5], 6, 'abc', [7], [8, [9, 10]]]

这里有几个问题:

  • 一个元素6只是一个标量;它是不可迭代的,所以上面的路由在这里会失败。
  • 一个元素,'abc'在技术上是可迭代的(所有str都是)。然而,在行之间读一点,你不想这样对待它——你想把它当作一个元素。
  • 最后一个元素,[8, [9, 10]]本身是一个嵌套的可迭代对象。基本列表理解和chain.from_iterable只提取“1级向下”。

您可以通过以下方式解决此问题:

>>> from collections import Iterable>>> from six import string_types
>>> def flatten(obj):...     for i in obj:...         if isinstance(i, Iterable) and not isinstance(i, string_types):...             yield from flatten(i)...         else:...             yield i

>>> list(flatten(obj))[1, 2, 3, 4, 5, 6, 'abc', 7, 8, 9, 10]

在这里,您检查子元素(1)是否可以与#0(来自itertools的ABC)一起迭代,但也要确保(2)元素是没有“类字符串”。

这可能不是最有效的方法,但我想放一个单行(实际上是两行)。两个版本都可以在任意层次结构嵌套列表上工作,并利用语言特性(Python 3.5)和递归。

def make_list_flat (l):flist = []flist.extend ([l]) if (type (l) is not list) else [flist.extend (make_list_flat (e)) for e in l]return flist
a = [[1, 2], [[[[3, 4, 5], 6]]], 7, [8, [9, [10, 11], 12, [13, 14, [15, [[16, 17], 18]]]]]]flist = make_list_flat(a)print (flist)

输出是

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]

这以深度优先的方式工作。递归向下,直到找到一个非列表元素,然后扩展局部变量flist,然后将其回滚到父级。每当返回flist时,它都会在列表理解中扩展到父级的flist。因此,在根处,返回一个平面列表。

上面的一个创建了几个本地列表并返回它们用于扩展父列表。我认为解决这个问题的方法可能是创建一个全局flist,如下所示。

a = [[1, 2], [[[[3, 4, 5], 6]]], 7, [8, [9, [10, 11], 12, [13, 14, [15, [[16, 17], 18]]]]]]flist = []def make_list_flat (l):flist.extend ([l]) if (type (l) is not list) else [make_list_flat (e) for e in l]
make_list_flat(a)print (flist)

输出再次

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]

虽然我现在还不确定效率。

您可以使用listextend方法。它显示最快:

flat_list = []for sublist in l:flat_list.extend(sublist)

性能:

import functoolsimport itertoolsimport numpyimport operatorimport perfplot

def functools_reduce_iconcat(a):return functools.reduce(operator.iconcat, a, [])

def itertools_chain(a):return list(itertools.chain.from_iterable(a))

def numpy_flat(a):return list(numpy.array(a).flat)

def extend(a):n = []
list(map(n.extend, a))
return n

perfplot.show(setup = lambda n: [list(range(10))] * n,kernels = [functools_reduce_iconcat, extend, itertools_chain, numpy_flat],n_range = [2**k for k in range(16)],xlabel = 'num lists',)

输出:

在此输入图片描述

有几个答案具有与下面相同的递归附加方案,但没有一个使用try,这使得解决方案更健壮,Pythonic

def flatten(itr):for x in itr:try:yield from flatten(x)except TypeError:yield x

用法:这是一个生成器,您通常希望将其包含在list()tuple()等可迭代生成器中,或者在for循环中使用它。

这种解决方案的优点是:

  • 适用于任何类型的可迭代(甚至是未来的!)
  • 适用于任何组合和嵌套深度
  • 如果顶层包含裸露项目也有效
  • 没有依赖
  • 快速高效(您可以将嵌套的可迭代部分展平,而不会在不需要的剩余部分上浪费时间)
  • 多功能(您可以使用它来构建您选择的可迭代对象或在循环中)

注意:由于所有可迭代对象是扁平化的,因此字符串被分解为单个字符的序列。如果你不喜欢/想要这种行为,你可以使用以下版本来过滤掉扁平化的可迭代对象,如字符串和字节:

def flatten(itr):if type(itr) in (str,bytes):yield itrelse:for x in itr:try:yield from flatten(x)except TypeError:yield x
np.hstack(listoflist).tolist()

我想要一个可以处理多个嵌套的解决方案(例如[[1], [[[2]], [3]]], [1, 2, 3]),但也不是递归的(我有一个很大的递归级别,我得到了一个递归错误。

这就是我想出的:

def _flatten(l) -> Iterator[Any]:stack = l.copy()while stack:item = stack.pop()if isinstance(item, list):stack.extend(item)else:yield item

def flatten(l) -> Iterator[Any]:return reversed(list(_flatten(l)))

和测试:

@pytest.mark.parametrize('input_list, expected_output', [([1, 2, 3], [1, 2, 3]),([[1], 2, 3], [1, 2, 3]),([[1], [2], 3], [1, 2, 3]),([[1], [2], [3]], [1, 2, 3]),([[1], [[2]], [3]], [1, 2, 3]),([[1], [[[2]], [3]]], [1, 2, 3]),])def test_flatten(input_list, expected_output):assert list(flatten(input_list)) == expected_output

一个非递归函数,用于展平任何深度的列表列表:

def flatten_list(list1):out = []inside = list1while inside:x = inside.pop(0)if isinstance(x, list):inside[0:0] = xelse:out.append(x)return out
l = [[[1,2],3,[4,[[5,6],7],[8]]],[9,10,11]]flatten_list(l)# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

根据您的列表[[1, 2, 3], [4, 5, 6], [7], [8, 9]],即1个列表级别,我们可以简单地使用sum(list,[])而不使用任何库

sum([[1, 2, 3], [4, 5, 6], [7], [8, 9]],[])# [1, 2, 3, 4, 5, 6, 7, 8, 9]

当内部存在元组或数字时扩展此方法的优势。只需将map的每个元素的映射函数添加到列表中

#For only tuplesum(list(map(list,[[1, 2, 3], (4, 5, 6), (7,), [8, 9]])),[])# [1, 2, 3, 4, 5, 6, 7, 8, 9]
#In general
def convert(x):if type(x) is int or type(x) is float:return [x]else:return list(x)
sum(list(map(convert,[[1, 2, 3], (4, 5, 6), 7, [8, 9]])),[])# [1, 2, 3, 4, 5, 6, 7, 8, 9]

这里中,这种方法在内存方面的缺点有一个明确的解释。简而言之,它递归地创建列表对象,应该避免:(

如果我想在前面的答案中添加一些东西,这是我的递归flatten函数,它不仅可以展平嵌套列表,还可以展平任何给定的容器或任何通常可以抛出项目的对象。这也适用于任何深度的嵌套,它是一个懒惰的迭代器,可以根据请求生成项目:

def flatten(iterable):# These types won't considered a sequence or generally a containerexclude = str, bytes
for i in iterable:try:if isinstance(i, exclude):raise TypeErroriter(i)except TypeError:yield ielse:yield from flatten(i)

通过这种方式,您可以排除不想被扁平化的类型,例如str或其他类型。

这个想法是,如果一个对象可以传递iter(),它就准备好产生项目。因此,可迭代对象甚至可以将生成器表达式作为一个项目。

有人可能会争辩:为什么你在OP没有要求的情况下写这个通用的?好吧,你是对的。我只是觉得这可能会帮助某人(就像它对我自己一样)。

测试用例:

lst1 = [1, {3}, (1, 6), [[3, 8]], [[[5]]], 9, ((((2,),),),)]lst2 = ['3', B'A', [[[(i ** 2 for i in range(3))]]], range(3)]
print(list(flatten(lst1)))print(list(flatten(lst2)))

输出:

[1, 3, 1, 6, 3, 8, 5, 9, 2]['3', b'A', 0, 1, 4, 0, 1, 2]

不是一行,但是看到这里的所有答案,我想这个长列表错过了一些模式匹配,所以在这里:)

这两种方法可能效率不高,但无论如何,它很容易阅读(至少对我来说;也许我被函数式编程宠坏了):

def flat(x):match x:case []:return []case [[*sublist], *r]:return [*sublist, *flat(r)]

第二个版本考虑列表的列表……无论嵌套:

def flat(x):match x:case []:return []case [[*sublist], *r]:return [*flat(sublist), *flat(r)]case [h, *r]:return [h, *flat(r)]

考虑到列表只有整数:

import rel = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]list(map(int,re.sub('(\[|\])','',str(l)).split(',')))
def flatten_array(arr):result = []for item in arr:if isinstance(item, list):for num in item:result.append(num)else:result.append(item)return result
print(flatten_array([1, 2, [3, 4, 5], 6, [7, 8], 9]))// output: [1, 2, 3, 4, 5, 6, 7, 8, 9]

我建议使用产量语句和产量从的生成器。举个例子:

from collections.abc import Iterable
def flatten(items, ignore_types=(bytes, str)):"""Flatten all of the nested lists to the one. Ignoring flatting of iterable types str and bytes by default."""for x in items:if isinstance(x, Iterable) and not isinstance(x, ignore_types):yield from flatten(x)else:yield x
values = [7, [4, 3, 5, [7, 3], (3, 4), ('A', {'B', 'C'})]]
for v in flatten(values):print(v)

如果您想取消嵌套所有内容并保留一个不同的元素列表,您也可以使用它。

list_of_lists = [[1,2], [2,3], [3,4]]list(set.union(*[set(s) for s in list_of_lists]))

对于一个包含多个列表的列表,这里有一个对我有效的递归解决方案,我希望是正确的:

# Question 4def flatten(input_ls=[]) -> []:res_ls = []res_ls = flatten_recursive(input_ls, res_ls)
print("Final flatten list solution is: \n", res_ls)
return res_ls

def flatten_recursive(input_ls=[], res_ls=[]) -> []:tmp_ls = []
for i in input_ls:if isinstance(i, int):res_ls.append(i)else:tmp_ls = itmp_ls.append(flatten_recursive(i, res_ls))
print(res_ls)return res_ls

flatten([0, 1, [2, 3], 4, [5, 6]])  # testflatten([0, [[[1]]], [[2, 3], [4, [[5, 6]]]]])

输出:

[0, 1, 2, 3][0, 1, 2, 3, 4, 5, 6][0, 1, 2, 3, 4, 5, 6]Final flatten list solution is:[0, 1, 2, 3, 4, 5, 6][0, 1][0, 1][0, 1][0, 1, 2, 3][0, 1, 2, 3, 4, 5, 6][0, 1, 2, 3, 4, 5, 6][0, 1, 2, 3, 4, 5, 6][0, 1, 2, 3, 4, 5, 6][0, 1, 2, 3, 4, 5, 6]Final flatten list solution is:[0, 1, 2, 3, 4, 5, 6]

在没有任何库的情况下在python中执行的最简单方法

这个函数也适用于多维列表

使用递归我们可以实现列表内列表的任意组合,我们可以在不使用任何库的情况下将其展平。

#Devilx = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]

output = []def flatten(v):if isinstance(v, int):output.append(v)if isinstance(v, list):for i in range(0, len(v)):flatten(v[i])
flatten(x)print("Output:", output)#Output: [1, 2, 3, 4, 5, 6, 7, 8, 9]
#Adding more dimensionsx = [ [1, [2, 3, [4, 5], [6]], 7 ], [8, [9, [10]]] ]flatten(x)print("Output:", output)#Output: [1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

我创建了一个小函数,基本上可以扁平化任何东西。您可以使用pip获取它:pip安装平台

from flatten_everything import flatten_everythingwithoutprotection=list(flatten_everything([1,1,2,[3, 4, 5, [6, 3, [2, 5, ["sfs", "sdfsfdsf",]]]],1,3,34,[55,{"brand": "Ford", "model": "Mustang", "year": 1964, "yearxx": 2020},pd.DataFrame({"col1": [1, 2], "col2": [3, 4]}),{"col1": [1, 2], "col2": [3, 4]},55,{"k32", 34},np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]),(np.arange(22), np.eye(2, 2), 33),],]))print(withoutprotection)output:[1, 1, 2, 3, 4, 5, 6, 3, 2, 5, 'sfs', 'sdfsfdsf', 1, 3, 34, 55, 'Ford', 'Mustang', 1964, 2020, 1, 2, 3, 4, 1, 2, 3, 4, 55, 34, 'k32', 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 1.0, 0.0, 0.0, 1.0, 33]

您甚至可以保护对象不被压扁:

from flatten_everything import ProtectedDict,ProtectedList,ProtectedTuplewithprotection=list(flatten_everything([1,1,2,[3, 4, 5, [6, 3, [2, 5, ProtectedList(["sfs", "sdfsfdsf",])]]],1,3,34,[55,ProtectedDict({"brand": "Ford", "model": "Mustang", "year": 1964, "yearxx": 2020}),pd.DataFrame({"col1": [1, 2], "col2": [3, 4]}),{"col1": [1, 2], "col2": [3, 4]},55,{"k32", 34},np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]),ProtectedTuple((np.arange(22), np.eye(2, 2), 33)),],]))print(withprotection)output:[1, 1, 2, 3, 4, 5, 6, 3, 2, 5, ['sfs', 'sdfsfdsf'], 1, 3, 34, 55, {'brand': 'Ford', 'model': 'Mustang', 'year': 1964, 'yearxx': 2020}, 1, 2, 3, 4, 1, 2, 3, 4, 55, 34, 'k32', 1, 2, 3, 4, 5, 6, 7, 8, (array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,17, 18, 19, 20, 21]), array([[1., 0.], [0., 1.]]), 33)]

如果你有一个numpy数组a

a = np.array([[1,2], [3,4]])a.flatten('C')

生产:

[1, 2, 3, 4]

np.flatten也接受其他参数:

  • C
  • F
  • A
  • K

有关参数的更多详细信息可用这里