最近数据处理时遇到一个需求,需要将一个多维列表降为一维列表,原列表维度不限,转化后的元素顺序不变,例如源列表:
[1,2,[1,3,[4,5,[7,8]]],['a','b',['c','d']]]
需转换为:
[1, 2, 1, 3, 4, 5, 7, 8, 'a', 'b', 'c', 'd']
1. 由于维度不限,因此只能用递归方式定义函数,定义如下:
def multi_to_single(x):
y = []
for i in x:
if type(i) is list:
y += multi_to_single(i)
else:
y.append(i)
return y
测试一下:
lis1 = [1,2,[1,3,[4,5,[7,8]]],['a','b',['c','d']]]
lis2 = [1,[2,3],4]
print(multi_to_single(lis1))
print(multi_to_single(lis2))
输出:
[1, 2, 1, 3, 4, 5, 7, 8, 'a', 'b', 'c', 'd']
[1, 2, 3, 4]
2. lambda方式定义:一行代码即可实现,原理也是递归,但不太好理解
multi_to_single2 = lambda x: [y for l in x for y in multi_to_single2(l)] if type(x) is list else [x]
multi_to_single3 = lambda x: sum(map(multi_to_single3,x),[]) if type(x) is list else[x]
print(multi_to_single2(lis1))
print(multi_to_single3(lis1))
输出:
[1, 2, 1, 3, 4, 5, 7, 8, 'a', 'b', 'c', 'd']
[1, 2, 1, 3, 4, 5, 7, 8, 'a', 'b', 'c', 'd']
测试结果跟1完全一样。Amazing!
multi_to_single3采用map遍历list每个元素,代替了列表推导式,写法更简洁一些,同样可以把multi_to_single3还原为普通定义函数:
def multi_to_single4(x):
if type(x) is list:
return sum(map(multi_to_single4,x),[])
else:
return [x]
print(multi_to_single4(lis))
输出:
[1, 2, 1, 3, 4, 5, 7, 8, 'a', 'b', 'c', 'd']