zl程序教程

您现在的位置是:首页 >  其他

当前栏目

扁平化列表,哪个方法更快?

2023-03-14 22:41:21 时间

在平时的编码过程中,经常会碰到嵌套列表扁平化的需求,比如说把列表[[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,运行结果如下:

结果:前两种方法比较慢,不推荐使用,后面四种方法差别不大,随你挑。

最后的话

编程最重要的就是动手,当你出现选择困难时,不妨写几个简单的函数,跑起来测试一下,你心里就有答案了。

如果非要弄个明白的话,可以看看相关函数或标准库的源代码,不过这可能要花费更多的时间。

如果有收获,请点赞支持,感谢阅读。