当前位置:首页 > 科技  > 软件

九个让你的 Python 代码更快的小技巧

来源: 责编: 时间:2024-01-09 08:53:03 352观看
导读哈喽大家好,我是咸鱼我们经常听到 “Python 太慢了”,“Python 性能不行”这样的观点。但是,只要掌握一些编程技巧,就能大幅提升 Python 的运行速度。今天就让我们一起来看下让 Python 性能更高的 9 个小技巧原文链接:http

哈喽大家好,我是咸鱼P4s28资讯网——每日最新资讯28at.com

我们经常听到 “Python 太慢了”,“Python 性能不行”这样的观点。但是,只要掌握一些编程技巧,就能大幅提升 Python 的运行速度。P4s28资讯网——每日最新资讯28at.com

今天就让我们一起来看下让 Python 性能更高的 9 个小技巧P4s28资讯网——每日最新资讯28at.com

原文链接:P4s28资讯网——每日最新资讯28at.com

https://medium.com/techtofreedom/9-fabulous-python-tricks-that-make-your-code-more-elegant-bf01a6294908P4s28资讯网——每日最新资讯28at.com

字符串拼接的技巧

如果有大量字符串等待处理,字符串连接将成为 Python 的瓶颈。P4s28资讯网——每日最新资讯28at.com

一般来讲,Python 中有两种字符串拼接方式:P4s28资讯网——每日最新资讯28at.com

  • 使用该 join() 函数将字符串列表合并为一个字符串
  • 使用 + or += 符号将每个字符串加成一个

那么哪种方式更快呢?我们一起来看一下P4s28资讯网——每日最新资讯28at.com

mylist = ["Yang", "Zhou", "is", "writing"]# Using '+'def concat_plus():    result = ""    for word in mylist:        result += word + " "    return result# Using 'join()'def concat_join():    return " ".join(mylist)# Directly concatenation without the listdef concat_directly():    return "Yang" + "Zhou" + "is" + "writing"
import timeitprint(timeit.timeit(concat_plus, number=10000))# 0.002738415962085128print(timeit.timeit(concat_join, number=10000))# 0.0008482920238748193print(timeit.timeit(concat_directly, number=10000))# 0.00021425005979835987

如上所示,对于拼接字符串列表, join() 方法比在 for 循环中逐个添加字符串更快。P4s28资讯网——每日最新资讯28at.com

原因很简单。一方面,字符串是 Python 中的不可变数据,每个 += 操作都会导致创建一个新字符串并复制旧字符串,这会导致非常大的开销。P4s28资讯网——每日最新资讯28at.com

另一方面,.join() 方法是专门为连接字符串序列而优化的。它预先计算结果字符串的大小,然后一次性构建它。因此,它避免了与循环中 += 操作相关的开销,因此速度更快。P4s28资讯网——每日最新资讯28at.com

但是,我们发现最快其实是直接用 + 拼接字符串,这是因为:P4s28资讯网——每日最新资讯28at.com

  • Python 解释器可以在编译时优化字符串的连接,将它们转换为单个字符串。因为没有循环迭代或函数调用,所以它是一个非常高效的操作。
  • 由于所有字符串在编译时都是已知的,因此 Python 可以非常快速地执行此操作,比循环中的运行时连接甚至优化 .join() 方法快得多。

总之,如果需要拼接字符串列表,请选择 join() ;如果直接拼接字符串,只需使用 + 即可。P4s28资讯网——每日最新资讯28at.com

创建列表的技巧

Python 中创建列表的两种常见方法是:P4s28资讯网——每日最新资讯28at.com

  • 使用函数 list()
  • [] 直接使用

我们来看下这两种方法的性能P4s28资讯网——每日最新资讯28at.com

import timeitprint(timeit.timeit('[]', number=10 ** 7))# 0.1368238340364769print(timeit.timeit(list, number=10 ** 7))# 0.2958830420393497

结果表明,执行 list() 函数比直接使用 [] 要慢。P4s28资讯网——每日最新资讯28at.com

这是因为 是 [] 字面语法(literal syntax),而 list() 是构造函数调用。毫无疑问,调用函数需要额外的时间。P4s28资讯网——每日最新资讯28at.com

同理,在创建字典时,我们也应该利用 {} 而不是 dict()P4s28资讯网——每日最新资讯28at.com

成员关系测试的技巧

成员关系测试的性能很大程度上取决于底层数据结构P4s28资讯网——每日最新资讯28at.com

import timeitlarge_dataset = range(100000)search_element = 2077large_list = list(large_dataset)large_set = set(large_dataset)def list_membership_test():    return search_element in large_listdef set_membership_test():    return search_element in large_setprint(timeit.timeit(list_membership_test, number=1000))# 0.01112208398990333print(timeit.timeit(set_membership_test, number=1000))# 3.27499583363533e-05

如上面的代码所示,集合中的成员关系测试比列表中的成员关系测试要快得多。P4s28资讯网——每日最新资讯28at.com

这是为什么呢?P4s28资讯网——每日最新资讯28at.com

  • 在 Python 列表中,成员关系测试 ( element in list ) 是通过遍历每个元素来完成的,直到找到所需的元素或到达列表的末尾。因此,此操作的时间复杂度为 O(n)。
  • Python 中的集合是作为哈希表实现的。在检查成员资格 ( element in set ) 时,Python 使用哈希机制,其时间复杂度平均为 O(1)。

这里的技巧重点是在编写程序时仔细考虑底层数据结构。利用正确的数据结构可以显著加快我们的代码速度。P4s28资讯网——每日最新资讯28at.com

使用推导式而不是 for 循环

Python 中有四种类型的推导式:列表、字典、集合和生成器。它们不仅为创建相对数据结构提供了更简洁的语法,而且比使用 for 循环具有更好的性能。P4s28资讯网——每日最新资讯28at.com

因为它们在 Python 的 C 实现中进行了优化。P4s28资讯网——每日最新资讯28at.com

import timeitdef generate_squares_for_loop():    squares = []    for i in range(1000):        squares.append(i * i)    return squaresdef generate_squares_comprehension():    return [i * i for i in range(1000)]print(timeit.timeit(generate_squares_for_loop, number=10000))# 0.2797503340989351print(timeit.timeit(generate_squares_comprehension, number=10000))# 0.2364629579242319

上面的代码是列表推导式和 for 循环之间的简单速度比较。如结果所示,列表推导式速度更快。P4s28资讯网——每日最新资讯28at.com

访问局部变量速度更快

在 Python 中,访问局部变量比访问全局变量或对象的属性更快。P4s28资讯网——每日最新资讯28at.com

import timeitclass Example:    def __init__(self):        self.value = 0obj = Example()def test_dot_notation():    for _ in range(1000):        obj.value += 1def test_local_variable():    value = obj.value    for _ in range(1000):        value += 1    obj.value = valueprint(timeit.timeit(test_dot_notation, number=1000))# 0.036605041939765215print(timeit.timeit(test_local_variable, number=1000))# 0.024470250005833805

原理也很简单:当编译一个函数时,它内部的局部变量是已知的,但其他外部变量需要时间来检索。P4s28资讯网——每日最新资讯28at.com

优先考虑内置模块和库

当我们讨论 Python 的时候,通常指的是 CPython,因为 CPython 是 Python 语言的默认和使用最广泛的实现。P4s28资讯网——每日最新资讯28at.com

考虑到它的大多数内置模块和库都是用C语言编写的,C语言是一种更快、更低级的语言,我们应该利用它的内置库,避免重复造轮子。P4s28资讯网——每日最新资讯28at.com

import timeitimport randomfrom collections import Counterdef count_frequency_custom(lst):    frequency = {}    for item in lst:        if item in frequency:            frequency[item] += 1        else:            frequency[item] = 1    return frequencydef count_frequency_builtin(lst):    return Counter(lst)large_list = [random.randint(0, 100) for _ in range(1000)]print(timeit.timeit(lambda: count_frequency_custom(large_list), number=100))# 0.005160166998393834print(timeit.timeit(lambda: count_frequency_builtin(large_list), number=100))# 0.002444291952997446

上面的程序比较了计算列表中元素频率的两种方法。正如我们所看到的,利用 collections 模块的内置计数器比我们自己编写 for 循环更快、更简洁、更好。P4s28资讯网——每日最新资讯28at.com

使用缓存装饰器

缓存是避免重复计算和提高程序速度的常用技术。P4s28资讯网——每日最新资讯28at.com

幸运的是,在大多数情况下,我们不需要编写自己的缓存处理代码,因为 Python 提供了一个开箱即用的装饰器 — @functools.cache 。P4s28资讯网——每日最新资讯28at.com

例如,以下代码将执行两个斐波那契数生成函数,一个具有缓存装饰器,但另一个没有:P4s28资讯网——每日最新资讯28at.com

import timeitimport functoolsdef fibonacci(n):    if n in (0, 1):        return n    return fibonacci(n - 1) + fibonacci(n - 2)@functools.cachedef fibonacci_cached(n):    if n in (0, 1):        return n    return fibonacci_cached(n - 1) + fibonacci_cached(n - 2)# Test the execution time of each functionprint(timeit.timeit(lambda: fibonacci(30), number=1))# 0.09499712497927248print(timeit.timeit(lambda: fibonacci_cached(30), number=1))# 6.458023563027382e-06

可以看到 functools.cache  装饰器如何使我们的代码运行得更快。P4s28资讯网——每日最新资讯28at.com

缓存版本的速度明显更快,因为它缓存了先前计算的结果。因此,它只计算每个斐波那契数一次,并从缓存中检索具有相同参数的后续调用。P4s28资讯网——每日最新资讯28at.com

while 1 VS while True

如果要创建无限 while 循环,我们可以使用 while True or while 1 .P4s28资讯网——每日最新资讯28at.com

它们的性能差异通常可以忽略不计。但有趣的是, while 1 稍微快一点。P4s28资讯网——每日最新资讯28at.com

这是因为是 1 字面量,但 True 是一个全局名称,需要在 Python 的全局作用域中查找。所以 1 的开销很小。P4s28资讯网——每日最新资讯28at.com

import timeitdef loop_with_true():    i = 0    while True:        if i >= 1000:            break        i += 1def loop_with_one():    i = 0    while 1:        if i >= 1000:            break        i += 1print(timeit.timeit(loop_with_true, number=10000))# 0.1733035419601947print(timeit.timeit(loop_with_one, number=10000))# 0.16412191605195403

正如我们所看到的,确实 while 1 稍微快一些。P4s28资讯网——每日最新资讯28at.com

然而,现代 Python 解释器(如 CPython )是高度优化的,这种差异通常是微不足道的。所以我们不需要担心这个可以忽略不计的差异。更不用说 while True 比 while 1 可读性更好。P4s28资讯网——每日最新资讯28at.com

按需导入 Python 模块

在 Python 脚本开头导入所有模块似乎是每个人都会这么做的操作,事实上我们没有必要导入全部的模块。如果模块太大,则根据需要导入它是一个更好的主意。P4s28资讯网——每日最新资讯28at.com

def my_function():    import heavy_module    # rest of the function

如上面的代码所示,heavy_module 在函数中导入。这是一种“延迟加载”的思想:只有 my_function 被调用的时候该模块才会被导入。P4s28资讯网——每日最新资讯28at.com

这种方法的好处是,如果 my_function 在脚本执行期间从未调用过,则 heavy_module 永远不会加载,从而节省资源并减少脚本的启动时间。P4s28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-58996-0.html九个让你的 Python 代码更快的小技巧

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 六个必知的PyCharm实用技巧

下一篇: 智能体验升级!搭载安第斯大模型和全新小布的 OPPO Find X7 系列正式发布

标签:
  • 热门焦点
  • Golang 中的 io 包详解:组合接口

    io.ReadWriter// ReadWriter is the interface that groups the basic Read and Write methods.type ReadWriter interface { Reader Writer}是对Reader和Writer接口的组合,
  • 只需五步,使用start.spring.io快速入门Spring编程

    步骤1打开https://start.spring.io/,按照屏幕截图中的内容创建项目,添加 Spring Web 依赖项,并单击“生成”按钮下载 .zip 文件,为下一步做准备。请在进入步骤2之前进行解压。图
  • 使用Webdriver-manager解决浏览器与驱动不匹配所带来自动化无法执行的问题

    1、前言在我们使用 Selenium 进行 UI 自动化测试时,常常会因为浏览器驱动与浏览器版本不匹配,而导致自动化测试无法执行,需要手动去下载对应的驱动版本,并替换原有的驱动,可能还
  • 一文搞定Java NIO,以及各种奇葩流

    大家好,我是哪吒。很多朋友问我,如何才能学好IO流,对各种流的概念,云里雾里的,不求甚解。用到的时候,现百度,功能虽然实现了,但是为什么用这个?不知道。更别说效率问题了~下次再遇到,
  • 小红书1周涨粉49W+,我总结了小白可以用的N条涨粉笔记

    作者:黄河懂运营一条性教育视频,被54万人“珍藏”是什么体验?最近,情感博主@公主是用鲜花做的,火了!仅仅凭借一条视频,光小红书就有超过128万人,为她疯狂点赞!更疯狂的是,这
  • 猿辅导与新东方的两种“归途”

    作者|卓心月 出品|零态LT(ID:LingTai_LT)如何成为一家伟大企业?答案一定是对“势”的把握,这其中最关键的当属对企业战略的制定,且能够站在未来看现在,即使这其中的
  • 一条抖音4亿人围观 ! 这家MCN比无忧传媒还野

    作者:Hiu 来源:互联网品牌官01 擦边少女空降热搜,幕后推手曝光被网友誉为“纯欲天花板”的女网红井川里予,近期因为一组哥特风照片登上热搜,引发了一场互联网世界关于
  • 品牌洞察丨服务本地,美团直播成效几何?

    来源:17PR7月11日,美团App首页推荐位出现“美团直播”的固定入口。在直播聚合页面,外卖“神枪手”直播间、美团旅行直播间、美团买菜直播间等均已上线,同时
  • 微软发布Windows 11新版 引入全新任务栏状态

    近日,微软发布了Windows 11新版,而Build 22563更新主要引入了几周前曝光的平板模式任务栏等,系统更流畅了。更新中,Windows 11加入了专门针对平板优化的任务栏
Top