在平时的编码过程中,经常会碰到嵌套列表扁平化的需求,比如说把列表[[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,运行结果如下:
结果:前两种方法比较慢,不推荐使用,后面四种方法差别不大,随你挑。