鄂尔多斯市建设厅网站小学做试卷的网站
news/
2025/9/23 1:33:36/
文章来源:
鄂尔多斯市建设厅网站,小学做试卷的网站,深圳龙岗区吉华街道邮编,中国商业银行官网前言
我们常用的字符串拼接方法有两个#xff0c;一个是通过“”号实现字符串的拼接#xff0c;还一个就是通过join方法来实现拼接#xff0c;前者在写法上更加便利#xff0c;和数字之间的加法运算一样#xff0c;通常只有两个运算对象#xff0c;只不过他们的运算规则…前言
我们常用的字符串拼接方法有两个一个是通过“”号实现字符串的拼接还一个就是通过join方法来实现拼接前者在写法上更加便利和数字之间的加法运算一样通常只有两个运算对象只不过他们的运算规则有所不同字符的加法规则是“拼接”数字的加法规则是“数值相加”而join方法处理的对象通常是多个字符串他们使用相同的拼接符号进行拼接最终得到一个字符串。值得注意的是除了操作对象的个数不同以外这两个功能几乎可以相互平替对方。
例子
来看一个具体例子分别使用“方法和join方法实现n个字符串的拼接,如果使用”号实现可能会相对复杂需要一个额外的for循环因为它一次性只能操作两个字符串而使用join则方便很多具体代码实现如下当然除了简单实现这两个方法外还实现了clock这个装饰器用来统计执行的耗时和空间大小粗略计算。
from tools import clockclock(True, False)
def add(s_list):res for s in s_list:res sreturn resclock(True, False)
def join(s_list):return .join(s_list)def main():for i in range(9):s_count int(pow(10, i))s_list [abc for _ in range(s_count)]add(s_list)join(s_list)add_cost_time add.cost_timejoin_cost_time join.cost_timeprint(f字符串的个数:{s_count} add耗时:{add_cost_time}ns join耗时:{join_cost_time}ns, end )if join_cost_time 0:print(fadd耗时是join的{add_cost_time // join_cost_time}倍)else:print()if __name__ __main__:main()执行结果如下 通过运行结果可以发现随着操作的字符串的个数的增加add方法和join方法他们使用的空间大小几乎保持一致因为得到的结果是一样的但是从10^5这个量级开始add方法的耗时就比join方法的耗时明显高很多并且每增加一个量级耗时也会相应增加一个量级。那么为什么会有这样的一个结果呢
源码探索
如果想知道为什么那就必须要搞清楚这两个方法的实现方式和细节才能搞明白为什么会有如此大的差距。如果你经常看某个方法的具体实现方式的话以join方法为例我相信你肯定会立马按住ctrl键然后鼠标左键当然这里不同的编辑器和快捷键会有所差别跳到它的源代码 可惜这次不幸的是它只给你留下了一段注释和和一个占位符pass通过注释可以知道它告诉了我们join方法的功能就是通过指定的分隔符来拼接多个字符串的但是却没有透露给你它的实现细节。 对于有一定经验的小伙伴来说可能已经猜到答案了它的实现在它的源码中在更深的一个层次。没错它的实现在python的源代码中在c语言这一层。通过下面这个图你可能就知道了 str作为python中最常用的内建对象之一当然也在Objects这个目录中。至于它是如何找到并调用objects中对应方法的这个问题可以留给大家去探索虽然我也还没搞明白
如何找源码
在进行源码分析之前首要的任务就是如何找到它最重要的一个参考就是如上的截图它列举出来了python源代码中每个目录代表的含义其中Lib和Modules中包含了所有的标准库Objects包含了所有的Python内建对象通过这三个目录我们应该就可以找到大部分我们需要的内容了。 注意虽然这个是py2具体一点是py2.4左右的但是根据我的对比这些目录的含义基本上是没有变化的只不过它内部的具体内容特别是源代码可能发生了很大的变化如果你的版本越高的话。就拿我现在看的是py3.11的代码来看它的源代码几乎是重新写了一遍虽然只对比了几处。 join源码分析
str是python的内置对象因此它的源代码应该在Objects目录中具体的位置可以根据该目录下文件的命名来判断这个方法可能有点愚蠢因为完全凭经验没有具体的逻辑主要是我也没有找到更好的方法 。这里join方法的实现就在这个join.h文件中具体方法是(bytes_join)(PyObject *sep, PyObject *iterable)。我不知道大家第一眼看到这个源码的感觉是什么样的如果你对c语言掌握的比较好的话可能会感到很亲切如果你像我一样只是了解一点对c语言的掌握已经停留在了大一学习那会儿…的话可能会比较头疼哈哈哈。不过这些都不重要因为当我真正沉下心去看还是能够理解它的大概意思的看的过程中特别要注意它的注释和变量名对于python这样的知名项目的源码你绝对可以相信它取的变量名能够达到“见名之意”的作用这两个我认为是理解的它的关键切入点。此外还可以借助强大的AI来协助我们理解带代码如下图所示它基本上完全地解释了整个方法的步骤。 接下来我们进入正题排除掉开头的一些逻辑判断我们可以将这个方法的核心逻辑分为三点 计算出序列中所有字符串拼接起来需要开辟的空间 在这个循环计算的过程中可能有两个报错情况一个是itemlen PYSSIZE_T_MAX - sz和seplen PY_SSIZE_T_MAX - sz这个主要是防止需要开辟的空间大于最大值PYSSIZE_T_MAX另外一个报错就是sequence changed size during iteration这个报错我相信大家比较熟悉一不小心在循环中修改列表的大小就会报出这个错误。 申请空间 写入数据
注意这里是先计算出需要开辟的空间然后只进行一次空间的申请。 法的源码分析
还是和上面的一样如果对c语言了解比较浅的同学可以借助强大的ai来协助我们一起来理解源码 抛开一些判断的逻辑其大致的核心逻辑如下
1.计算出旧字符串的长度2.根据旧字符串的长度之和创建新的字符串对象3.分别将旧的left和right字符串写入到新的字符串中
注意这里创建新的对象时就会进行空间的申请 大家有没有发现不管是join方法还是“”法方法都会创建新的对象进行一次空间申请但是细心的小伙伴一定发现了如果随着操作对象的数量增加join方法始终都只需要进行一次空间的申请而“”法方法随着操作对象的数量的增加它申请空间的次数也会随之增加准确的说如果有nn2个操作对象那么“”法需要进行n-1次空间申请假设它们每次申请空间的耗时都相同那么对n个对象进行拼接的耗时比就是“”法/join n-1/1所以上面例子是不是就说得通啦。 更多内容可以前往博主的个人博客系统白日梦想园。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/911008.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!