• Code Anatomy - 编写高性能 Python 代码


    编写简短高效的 Python 代码并不总是那么容易或直接。然而,我们经常看到一段代码,却没有意识到其编写方式背后的思考过程。我们将看一下片段,它返回两个迭代之间的差异,以了解其结构。

    根据片段功能的描述,我们可以天真地写成这样:

    1. def difference(a, b):
    2. return [item for item in a if item not in b]

    此实现可能运行良好,但不考虑b. 如果第二个列表中有许多重复项,这会使代码花费更多的时间。为了解决这个问题,我们可以使用set()只保留列表中唯一值的方法:

    1. def difference(a, b):
    2. return [item for item in a if item not in set(b)]

    这个版本虽然看起来像是一个改进,但实际上可能比以前的版本慢。如果你仔细观察,你会发现set()每次都会调用 everyitem导致a结果set(b)被评估。这是一个示例,我们set()用另一种方法包装以更好地展示问题:

    1. def difference(a, b):
    2. return [item for item in a if item not in make_set(b)]
    3. def make_set(itr):
    4. print('Making set...')
    5. return set(itr)
    6. print(difference([1, 2, 3], [1, 2, 4]))
    7. # Making set...
    8. # Making set...
    9. # Making set...
    10. # [3]

    此问题的解决方案是set()在列表推导之前调用一次并存储结果以加快处理速度:

    1. def difference(a, b):
    2. _b = set(b)
    3. return [item for item in a if item not in _b]

    在性能方面值得一提的另一个选项是使用列表推导与filter()and list()。使用后一个选项实现相同的代码将导致如下所示:

    1. def difference(a, b):
    2. _b = set(b)
    3. return list(filter(lambda item: item not in _b, a))

    使用timeit分析最后两个代码示例的性能,很明显使用列表推导可以比替代方法快十倍。这是因为它是一种本地语言功能,其工作方式与简单循环非常相似,for没有额外函数调用的开销。这解释了为什么我们更喜欢它,除了可读性。

  • 相关阅读:
    逍遥魔兽:如何在服务器上挂机器人?
    eDDA(电子直接扣款授权)
    C语言实现三子棋小游戏(源码+教程)
    常用中间件分类
    WARING: UNPROTECTED PRIVATE KEY FILE!
    蓝桥杯倒计时47天!DFS基础——图的遍历
    https想访问本地部署的http://localhost接口
    Verilog generate
    Web3 招聘 | Bitget、MyShell、imToken、Arweave 多项目招聘中
    持续集成部署-k8s-命令行工具:基础命令的使用
  • 原文地址:https://blog.csdn.net/liuhao9999/article/details/125505664