所谓展开嵌套序列就是类似于[1,2,3,[3,4,[5,6]],7],这样的序列展开成[1,2,3,3,4,5,6,7]。
一、如果最外层列表里边都是小的列表,没有不可迭代的元素,可以这样做:
from collections import Iterable a = [[1,3],[2,4],[3,5]] x = [q for p in a if isinstance(p,Iterable) for q in p] print(x)
或者如果不允许使用其他库可以这样代替:
from collections import Iterable a = [[1,3],[2,4],[3,5]] x = [q for p in a if type(x) is list for q in p] #或者 x = [q for p in a if isinstance(p,list) for q in p]
print(x)
但是这样一来就只能是被list了 最初的可以识别任何可迭代的
二、如果列表里边有单个元素,那么用以上办法就会把单个元素给略去,因为他们不能迭代,即不是列表,这时候用下边这种方法:
from collections import Iterable a = [1, 3,[5, 6], [9, 10],15] x = sum((x if type(x) is list else [x] for x in a), []) print(x)
这个代码适合于单个元素的情况
三、但是,但是,以上这几个代码都不适合多重嵌套,只适合单层嵌套,即适合[1,[2,3],4,5],不适合[1,2,[3,[4,5]],6],即列表里边的列表里边还有列表
此时只能使用更为复杂的代码,一句已经不行
from collections import Iterable
def flatten(items, ignore_types=(str, bytes)): for x in items: if isinstance(x, Iterable) and not isinstance(x, ignore_types): #之所以加上isinstance(x, ignore_types),是为了防止有字符串,而把字符串给断成单个字母,如果只有数字列表,就可以吧Iterable去掉改成list,后边的这句也可以去掉 yield from flatten(x) #这个是精华,他会返回所有子例程的值,不能只写成yield else: yield x items = [1, 2, [3, 4, [5, 6], 7], 8] # Produces 1 2 3 4 5 6 7 8 for x in flatten(items): print(x)
def flatten(items, ignore_types=(str, bytes)): #这个是不用yield from的方法,需要加一个循环,这里也可以看出来两者的区别
for x in items:
if isinstance(x, Iterable) and not isinstance(x, ignore_types):
for i in flatten(x):
yield i
else:
yield x
这个是终极的,适合所有情况,因为是递归的。