扁平化列表,哪个方法更快?
在平时的编码过程中,经常会碰到嵌套列表扁平化的需求,比如说把列表[[1,2,3],[4,5]] 变成 [1,2,3,4,5],Python 有很多方法可以实现这一功能,到底哪个方法更快呢?我们今天就来试一试。
第一种方法:建一个空列表,遍历嵌套列表把元素逐一放入并返回:
def flatten1(lst: List[list]) -> list:
flat = []
for l in lst:
for x in l:
flat.append(x)
return flat
第二种方法:使用列表推导式:
def flatten2(lst: List[list]) -> list:
return [x for l in lst for x in l]
第三种方法:使用列表的 extend 方法:
def flatten3(lst: List[list]) -> list:
flat = []
for l in lst:
flat.extend(l)
return flat
第四种方法:使用 + 号:
def flatten4(lst: List[list]) -> list:
flat = []
for l in lst:
flat += l
return flat
第五种方法:使用 itertools.chain:
def flatten5(lst: List[list]) -> list:
return list(itertools.chain.from_iterable(lst))
第六种方法:使用 functools.reduce:
def flatten6(lst: List[list]) -> list:
return functools.reduce(operator.iconcat, lst, [])
你可以先猜一下,然后看看下面的运行结果:
import functools
import itertools
import operator
import random
import time
from typing import List
def flatten1(lst: List[list]) -> list:
flat = []
for l in lst:
for x in l:
flat.append(x)
return flat
def flatten2(lst: List[list]) -> list:
return [x for l in lst for x in l]
def flatten3(lst: List[list]) -> list:
flat = []
for l in lst:
flat.extend(l)
return flat
def flatten4(lst: List[list]) -> list:
flat = []
for l in lst:
flat += l
return flat
def flatten5(lst: List[list]) -> list:
return list(itertools.chain.from_iterable(lst))
def flatten6(lst: List[list]) -> list:
return functools.reduce(operator.iconcat, lst, [])
# +=
def time_f(f):
elapsed = 0.0
n = 100
M = 1000
N = 100
for _ in range(n):
lst = [[random.randint(0,1000000) for j in range(N)] for i in range(M)]
start = time.perf_counter()
f(lst)
elapsed += time.perf_counter() - start
print(f"{f.__name__} cost {elapsed/n * 1000 :.4f} ms")
if __name__ == '__main__':
time_f(flatten1)
time_f(flatten2)
time_f(flatten3)
time_f(flatten4)
time_f(flatten5)
time_f(flatten6)
运行环境:Python 3.8.5,运行结果如下:
结果:前两种方法比较慢,不推荐使用,后面四种方法差别不大,随你挑。
最后的话
编程最重要的就是动手,当你出现选择困难时,不妨写几个简单的函数,跑起来测试一下,你心里就有答案了。
如果非要弄个明白的话,可以看看相关函数或标准库的源代码,不过这可能要花费更多的时间。
如果有收获,请点赞支持,感谢阅读。
评论