一日一技:如何把多层嵌套的列表展平

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一日一技:如何把多层嵌套的列表展平相关的知识,希望对你有一定的参考价值。

一日一技:如何把多层嵌套的列表展平

技术图片

摄影:产品经理

有这样一个列表套列表的数据结构:


a = [1, 2, [3, 4, [5, 6, 7], 8], 9, [10, 11]]

现在想把它变为:

b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

遇到这种问题,肯定有很多人想到用递归和循环来实现:

def flat(deep_list, result):
for element in deep_list:
if isinstance(element, list):
flat(element, result)
else:
sult.append(element)
a = [1, 2, [3, 4, [5, 6, 7], 8], 9, [10, 11]]
result = []
flat(a, result)
print(result)

这样做确实能达到目的,但是需要把储存结果的列表作为参数不停递归传入。

实际上,如果使用生成器,这个问题就会变得简单很多:

def flat(deep_list):
for element in deep_list:
if isinstance(element, list):
yield from flat(element)
else:
yield element
a = [1, 2, [3, 4, [5, 6, 7], 8], 9, [10, 11]]
result = [x for x in flat(a)]
print(result)

在这个解法里面,使用了 yield和 yieldfrom实现生成器,当我们直接对生成器进行迭代的时候,就得到了结果。

yield from x
# 等价于
for g in x:
yield g

其中, yieldfrom是从Python 3.3开始引入的写法:

[x for x in flat(a)]

的时候,每一次循环都会进入到 flat生成器里面。在 flat里面,对传入的参数使用for循环进行迭代,如果拿到的元素不是列表,那么就直接抛出,送到上一层。如果当前已经是最上层了,那么就再一次抛出给外面的列表推导式。如果当前元素是列表,那么继续生成一个生成器,并对这个新的生成器进行迭代,并把每一个结果继续往上层抛出。

最终,每一个数字都会被一层一层往上抛出给列表推导式,从而获得需要的结果。

以上是关于一日一技:如何把多层嵌套的列表展平的主要内容,如果未能解决你的问题,请参考以下文章

一日一技:在 Python 里面如何合并多个有序列表并使得结果依然有序?

一日一技:如何从 Redis 的列表中一次性 pop 多条数据?

一日一技:如何把MongoDB作为循环队列

在 IF 语句中嵌套展平;重新键入多层展平

一日一技:不等长度列表的同时迭代

一日一技:不使用 try...except 掩盖一些已知异常