深入理解两个常用的Python技巧

1. 引言

只需简单搜索一下,就很容易获得许多试图告诉我们关于 Python 技巧的文章。这些技巧要么更 “Pythonic”,要么能让我们的程序更快。这些文章并没有错,因为大多数技巧都非常有用。事实上,我自己也写过很多这类文章。

然而,这类文章经常受到批判,因为没有适用于所有情况的技巧。这也是事实。在我看来,更重要的是了解这些技巧存在的背后的原因,这样我们才能明白什么时候该用,什么时候不该用。

在这篇文章中,我将选取其中常见的两种技巧,并对其背后的机制进行详细解释。

2. 更快地连接字符串

通常如何将字符串连接在一起?我们来看一个字符串列表,如下:

strs = ['Life', 'is', 'short,', 'I', 'use', 'Python']

当然,最直观的方法是循环列表,并使用 + 运算符连接所有带空格的子串。
在这里插入图片描述

在上述代码中,我们只需定义一个空字符串,然后在该字符串上不断添加空格和列表中的子字符串。最后,我们返回从第 2 个字符开始的结果字符串,这样前导的空格就会被忽略。
不过,在这种情况下,我们有一个更好的方法来实现它。那就是使用 join() 函数,如下所示。
在这里插入图片描述

它不仅可读性更强,而且速度更快。请看下面的性能对比。
在这里插入图片描述

3. 原因分析

接下来我们来分析二者的具体执行步骤,首先来分析第一种方案:

● 每个for循环都会在列表中查找字符串
● Python 执行器遇到表达式 result += ' ' + s时,会并为空格 ' ' 申请一个内存地址。
● 然后,执行器意识到需要将空格与字符串连接起来,因此它将申请字符串 s 的内存地址,即第一个循环的 "Life"
● 对于每次循环,执行器都需要申请两次内存地址,一次是空格,另一次是字符串
● 共有 12 次内存分配

接下来,让我们看看使用 join() 函数的步骤。

● 执行器将计算列表中有多少个字符串。共有 6 个。
● 这意味着用于字符串列表中的连接字符串需要重复 6-1=5 次。
● 它知道总共需要 11 个内存空间,因此所有这些空间都将一次性预先分配。
● 按顺序排列字符串,并返回结果。

因此,显而易见,内存分配次数是上述技巧性能提升的主要原因。

4. 使用集合而非列表

ListPython 中非常常用。但是,你有没有想过,我们是否应该使用其他东西呢?我们知道 Python 中的 列表List 的元素是有顺序的,但如果顺序并不重要呢?例如,有时我们只需要知道一个元素是否存在,此时Python中的集合 Set 就能满足我们的要求。在这种情况下,集合set的性能会比列表list 好得多。

让我们定义一个具有完全相同元素的列表和集合。

my_list = list(range(100))
my_set = set(range(100))

如上,二者都有从 099100 个整数。唯一不同的是数据结构类型。现在,假设我们要检查数字 "99 "是否在容器中,并比较其性能。
在这里插入图片描述

可见,列表的性能会因需要扫描的范围不同而变化。在上面的示例中,如果我们要测试列表中是否有 "0",那么其性能将与集合相同。如果我们测试的是位于中间的 "50",性能就会变差。如果我们测试的是最后一个元素,则会比其他情况慢得多。另一方面,集合的性能往往相当稳定。无论我们测试哪个数字,其性能都不会有太大的变化。

5. 原因分析

简而言之,列表和集合的数据结构完全不同。PythonSet 使用哈希表实现,而 Python List 是典型的数组。
在这里插入图片描述

                                      图1: 建立哈希表

哈希表是什么样的?一般来说,数值会被送入一个哈希函数,这个哈希函数会将原始数值转换成另一个数值,而这个新的数值会被用作哈希表的索引。
在这里插入图片描述

                                             图2:   验证 "值 3 "是否存在

现在,让我们来看看 Python中的 List,它是一种数组类型的数据结构。列表中的元素以固定的顺序链接在一起。
在这里插入图片描述

                                             图3:   Python 列表中的值

因此,当我们寻找某个值时,它必须从列表的开头开始,逐个元素检查,直到找到目标时(如果不匹配,则到达结尾)。

在这里插入图片描述

                                             图4:   Python 列表查找过程

因此,最幸运的情况是第一个列表中第一个元素就是我们要找的,结果会立即返回。最糟糕的情况是,我们要找的元素是列表中的最后一项。这也解释了为什么当我们试图在列表中查找 0、50 和 99 时,性能会有所不同。

6. 总结

在本文中,我挑选了两种常见的 Python 技巧,并尽力解释了其背后的原因。它为什么有效,为什么性能更好。这也将帮助我们决定何时使用这些技巧,您学废了嘛?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/782867.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯 java 承压计算

题目: 思路: 1:其中的数字代表金属块的重量(计量单位较大) 说明每个数字后面不一定有多少个0 2:假设每块原料的重量都十分精确地平均落在下方的两个金属块上,最后,所有的金属块的重量都严格精确地平分落在最底层的电子…

多维数组和交错数组笔记

1.) 关于数据的几个概念: Rank,即数组的维数,其值是数组类型的方括号之间逗号个数加上1。 Demo:利用一维数组显示斐波那契数列F(n) F(n-1) F(n-2) (n >2 ),每行显示5项,20项. static void Main(string[] args){int[] F n…

http响应练习—在服务器端渲染html(SSR)

一、什么是服务器端渲染(SSR) 简单说,就是在服务器上把网页生成好,整个的HTML页面生成出来,生成出的页面已经包含了所有必要的数据和结构信息,然后直接发给浏览器进行展现。 二、例题 要求搭建http服务&a…

slowhttp攻击漏洞原理解析和防御,以及LiqunKit 综合漏洞利用工具详细使用

slowhttp攻击漏洞原理解析和防御,以及LiqunKit 综合漏洞利用工具详细使用。 Slowhttp攻击是一种拒绝服务(DoS)攻击,它利用了HTTP协议的一些特性来耗尽服务器资源,导致服务器对正常请求的响应变慢或无法响应。这种攻击的特点是长时间占用服务器的连接,而不是发送大量流量…

JSQLParserException异常

前言 SQL中加入了租户字段&#xff0c;报这个错&#xff0c;可以查出数据&#xff0c;但是不多&#xff1b;SQL检查无问题 解决 原因一 引入新的SQL解析器检查解析SQL&#xff0c;与mybatis多租户无关 参考 <!--jsqlparser版本太低也无法解析&#xff0c;如2.0--> &…

2024 年高效开发的 React 生态系统

要使用 React 制作应用程序&#xff0c;需要熟悉正确的库来添加您需要的功能。例如&#xff0c;要添加某个功能&#xff08;例如身份验证或样式&#xff09;&#xff0c;您需要找到一个好的第三方库来处理它。 在这份综合指南中&#xff0c;我将向您展示我建议您在 2024 年使用…

C语言预处理详解

预处理是什么 在我们写完C语言程序的时候当我们开始运行程序时&#xff0c;程序会经过预处理&#xff0c;编译&#xff0c;汇编&#xff0c;链接这些过程之后才会生成可执行程序&#xff0c;这里我们讲的是预处理&#xff0c;预处理是编译的第一个阶段&#xff0c;在这个阶段&a…

传参的指针,你的值到底变了没?!(有关函数形参修改的另类案例)

我们都知道&#xff0c;想要在函数中修改某个变量的值&#xff0c;传变量本身是没有用的。原因在于不同的函数在不同的空间上&#xff0c;函数的生命周期随着函数的调用而结束&#xff0c;因此在函数内部进行的值操作是不会对函数外的变量产生影响的。所以在函数里面想要修改变…

C语言使用STM32开发板手搓高端家居洗衣机

目录 概要 成品效果 背景概述 1.开发环境 2.主要传感器。 技术细节 1. 用户如何知道选择了何种功能 2.启动后如何进行洗衣 3.如何将洗衣机状态上传至服务器并通过APP查看 4.洗衣过程、可燃气检测、OLED屏显示、服务器通信如何并发进行 小结 概要 本文章主要是讲解如…

C语言-写一个宏,可以将一个整数的二进制位的奇数位和偶数位交换。

0xaaaaaaaa...等是什么&#xff1f;-CSDN博客https://blog.csdn.net/Jason_from_China/article/details/137179252 #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #define SWAP(num) (((num & 0xAAAAAAAA) >> 1) | ((num & 0x55555555) << …

【C++】C到C++的入门知识

目录 1、C关键字 2、命名空间 2.1 命名空间的定义 2.2 命名空间的使用 2.2.1 加命名空间名称及作用域限定符 2.2.2 使用using将命名空间中某个成员引入 2.2.3 使用using namespace 命名空间名称引入 3、C输入&输出 4、缺省参数 4.1 缺省参数的概念 4.2 缺省参数的…

名字真的会影响我们的职业吗?

名字是我们身份的一部分&#xff0c;人们往往喜欢将一个人名字同一种具体的职业联系在一起&#xff0c;而如果这个人名字看上去更适合一项工作&#xff0c;那么他&#xff08;她&#xff09;就有更多的机会得到这份工作。因此&#xff0c;我们在给福主取名改名时也会与职业特点…

10.Python异常处理

为增强程序的健壮性&#xff0c;我们也需要考虑异常处理方面的内容。例如 &#xff0c;在读取文件时需要考虑文件不存在、文件格式不正确等异常情况。这 就是本章要介绍的异常处理。 1 第一个异常——除零异常 在数学中&#xff0c;任何整数都不能除以0&#xff0c;如果在计算…

PCL 计算点与圆的距离(3D)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 3D中的圆可以有圆心、半径以及法线来进行表示,如下图所示: 这里我们假设: Δ = P − C \Delta=P-C Δ

Wasm初上手

总之也是为了扩宽技术面吧。。。我也不知道为什么就想试试了&#xff0c;就酱。 参考阅读&#xff1a;极客时间《WebAssembly入门课》 安装wasm的编译器Emscripten。Emscripten 是一个“源到源”语言编译器工具集&#xff0c;这个工具集可以将 C/C 代码编译成对应 JavaScript 代…

CSS使用clip-path实现元素动画

前言&#xff1a; 在日常开发当中&#xff0c;如果想要开发多边形&#xff0c;一般都需要多个盒子或者伪元素的帮助&#xff0c;有没有一直办法能只使用一个盒子实现呢&#xff1f; 有的&#xff1a;css裁剪 目录 前言&#xff1a; clip-path到底是什么&#xff1f; clip-pa…

【御控物联】 JavaScript JSON结构转换(4):对象To对象——规则属性重组

文章目录 一、JSON结构转换是什么&#xff1f;二、术语解释三、案例之《JSON对象 To JSON对象》四、代码实现五、在线转换工具六、技术资料 一、JSON结构转换是什么&#xff1f; JSON结构转换指的是将一个JSON对象或JSON数组按照一定规则进行重组、筛选、映射或转换&#xff0…

赋值语句还能当判断条件?涨芝士了!

赋值和条件看似是C语言中毫不相关的两个概念&#xff0c;虽然实际过程中我猜测不会有太多这种不太符合常理的情况出现&#xff0c;但是现在在学习的过程中&#xff0c;为了出题而出题总是会整出一些花活出来.....这很难不让人联想起高中时一些大佬为了彰显自己的数学天赋而自己…

树莓派串口读取陀螺仪ky9250(mpu9250)数据

9轴姿态角度传感器&#xff0c;其中ky9250陀螺仪由于自带卡尔曼动态滤波算法方便用户使用。ky9250陀螺仪基本可以在各个平台上进行数据的读取&#xff08;如stm32\arduino\C#\Matlab\树莓\Unity3d\python\ROS\英飞凌\Nvidia jetson linux 等&#xff09; 1、树莓派和ky9250的接…

AcWing刷题-区间合并

校门外的树 区间合并&#xff1a; from typing import List def merge(intervals: List[List[int]]) -> List[List[int]]:# 按照第一个元素从小到大进行排序intervals.sort(keylambda x: x[0])# 初始化一个新的数组new_list list()for i in intervals:# 把第一个数组元素添…