位置: 编程技术 - 正文

详解Python字符串对象的实现(python中字符串的方法)

编辑:rootadmin

推荐整理分享详解Python字符串对象的实现(python中字符串的方法),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:python 字符串,python字符串的方法,python字符串的用法,python 字符串,python字符串方法总结,python字符串操作大全,python字符串操作大全,python 字符串,内容如对您有帮助,希望把文章链接给更多的朋友!

PyStringObject 结构体

Python 中的字符串对象在内部对应一个名叫 PyStringObject 的结构体。“ob_shash” 对应字符串经计算过的 hash值, “ob_sval” 指向一段长度为 “ob_size” 的字符串,且该字符串以‘null'结尾(为了兼容C)。“ob_sval”的初始大小为1个字节,且 ob_sval[0]=0(对应空字符串)。若你还想知道“ob_size”被定义的位置,可以看一看 object.h 头文件中 PyObject_VAR_HEAD 对应部分。“ob_sstate” 用来指示某个字符串是否已经存在于intern机制对应的字典中,后面我们会再次提到这一点。

字符串对象的创建

如下所示,当将一个新的字符串赋给一个变量时,发生了什么?

1>>> s1 = 'abc'运行以上代码时,内部的 C 函数 “PyString_FromString” 将被调用并生成类似下面的伪代码:

每次用到新的字符串时,都将分配一个字符串对象。

共享字符串对象

Python 有一个优雅的特性,就是变量之间的短字符串是共享的,这一特性可以节省所需的内存空间。短字符串就是那些长度为 0 个或者 1 个字节的字符串。而全局变量 “interned” 对应一个用于索引这些短字符串的字典。数组 “characters” 也可用于索引那些长度为 1 个字节的字符串,比如单个字母。后面我们将看到数组 “characters” 是如何被使用的。

下面一起看看:当你在 Python 脚本中将一个短字符串赋值给一个变量时,背后发生了哪些事情。

内容为 ‘a' 的字符串对象将被添加到 “interned” 字典中。字典中键(key)是一个指向该字符串对象的指针,而对应的值 就是一个相同的指针。在数组 “characters” 中,这一新的字符串对象在偏移量为 的位置被引用,因为字符 ‘a' 的ASCII码值便是 。变量 “s2” 也指向了这一字符串对象。

而,当另外一个变量也被相同的字符串 ‘a' 赋值时,又会如何呢?

1>>> s3 = 'a'上述代码执行后,将返回之前已创建的内容相同的字符串对象。因此,‘s1' 和 ‘s3' 两个变量都将指向同一个字符串对象。 数组 “characters” 便是用于检测字符串 ‘a' 是否已经存在,若存在,则返回指向该字符串对象的指针。

下面我们新建一个内容为 ‘c' 的短字符串:

1>>> s4 = 'c'那么,我们将得到如下结果:

详解Python字符串对象的实现(python中字符串的方法)

我们还能发现,当按照下面 Python 脚本中的方式对一个字符串元素进行访问时,数组 “characters” 仍有用武之地。

上面第二行代码中,返回的是数组 “characters” 偏移量为 的位置内的指针元素,而非新建一个值为 ‘a'的字符串。当我们访问某个字符串中的元素时,一个名叫 “string_item” d的函数将被调用,下方给出了函数体代码。其中,参数 ‘a' 便对应着字符串 “abc”,而参数 ‘i' 便是访问数组的索引值(本例中便为 0 ),函数返回的是指向某个字符串对象的指针。

数组 “characters” 也可用于函数名长度为 1 时的情形,如下所示:

>>> def a(): pass字符串查找

下面看看,当你在如下 Python 代码中进行字符串查找操作时,又会有那些事情发生呢?

函数 “find” 返回一个索引值,说明是在字符串 “abcd” 的哪个位置找到字符串 “s” 的。若字符串未找到,函数返回值为 -1。

那么,内部到底干了些啥事情?内部调用了一个名为 “fastsearch” 的函数。这个函数是一个介于 BoyerMoore 和 Horspool 算法之间的混合版本,它兼具两者的优良特性。

我们将 “s”(s = ‘adcabcdbdabcabd')称作主字符串,而将 “p”(p = ‘abcab')称作模式串。n 和 m 分别表示字符串 s 和 字符串 p 的长度,其中,n = , m = 5。

在如下代码段中,明显看到,程序将进行首次判定:若 m > n,我们就知道必然不能找到这样的索引号,因此函数直接返回 -1 即可。

当 m = 1 时,程序便在字符串 s 中一个个字符地进行遍历,若匹配成功则返回对应的索引位置。在本例中,变量 mode 值为 FAST_SEARCH,意味着我们想获取的是在主字符串中首次匹配的位置,而非模式串在主字符串中成功匹配的次数。

考虑其他情况,比如 m > 1。首先创建一个压缩的boyer-moore delta 1 table(对应BM算法中的坏字符规则),在此过程中需要声明两个变量:“mask” 和 “skip”。

“mask” 是一个 位的位掩码(bitmask),将其最低的 5 个特征位作为开关位。该掩码是通过和模式串 “p” 进行操作产生的。它设计成一个布隆过滤器(bloom filter),用于检测一个字符是否出现在当前字符串中。这种机制使查找操作十分迅速,但是存在伪正的情况(false positives)。关于布隆过滤器,你想有更多了解的话可以看看 这里 。对于本例,下方说明了位掩码具体是如何产生的。

字符串 “p” 的第一个字符为 ‘a'。字符‘a'的二进制表示为 = 。保留最低的 5 个特征位,我们得到了 ,因此变 “mask” 初次被设定为 (1 << 1)。当整个字符串 “p” 都经过处理后,mask 值为 。那么,我们应该如何使用这个位掩码呢?通过下方这行代码,我们用其来检测字符 “c” 位于字符串 “p” 哪个位置。

if ((mask & (1 << (c & 0x1F))))那么,字符 ‘a' 在字符串 “p”(‘abcab')中是否存在呢? & (1 << (‘a' & 0X1F)) 运算结果的值是否为 true 呢?由于 & (1 << (‘a' & 0X1F)) = & = ,可知 ‘a' 确实存在于 ‘abcab'。当检测字符 ‘d'时,我们得到的是 false,对于其他字符(从 ‘e' 到 ‘z')也是同样结果。因此,在本例中此类过滤器表现十分出众。 变量 “skip” 对应目标字符在主字符串中最后一个成功匹配的字符的索引位置(从后向前匹配)。假若模式串的最后一个匹配字符在主字符串中不存在,则 “skip” 值为 模式串 “p” 的长度减去 1。本例中,模式串最后一个为匹配字符位 ‘b',由于其在主串查找的当前位置向后跳两个字符后能够匹配到,因此变量 “skip” 的值为2。这个变量应用于一种名叫坏字符跳跃(bad-character skip)的规则。在如下示例中,p = ‘abcab',s = ‘adcabcaba'。从主串 “s” 的 4 号索引位置(从 0 开始计算)开始匹配,若字符匹配成功则向前继续匹配。第一个匹配失败的索引位置为 1(此处 ‘b' 不等于 ‘d')。我们可以看到,在模式串和主串最开始匹配的末端位置往后数三个字符,主串中也有一个 ‘b',而字符 ‘c' 也存在于 “p” 中,因此我们跳过了随后的 ‘b'。

下面,看下查找操作的循环部分(真实代码为 C 实现,而非 Python):

“s[i+m] not in p” 这行测试代码是基于位掩码实现的,“i += skip” 便对应坏字符跳跃。当主串下一个待匹配的字符在 “p” 中并未找到时,则执行 “i += m” 这行代码。

下面来看看,对于字符串 “p” 和 “s” 的匹配,算法具体是如何运行的。前三个步骤与上面类似,接着,字符 ‘d' 在字符串 “p” 并未找到,因此我们直接跳过等于“p”字符串长度的字符数,之后便迅速找到了一个匹配。

标签: python中字符串的方法

本文链接地址:https://www.jiuchutong.com/biancheng/379957.html 转载请保留说明!

上一篇:浅谈Python单向链表的实现(单向链表的基本操作)

下一篇:在Mac OS上搭建Python的开发环境(mac如何配置pycharm)

  • 捐赠免税会计分录
  • 湖南省增值税发票图片
  • 购买土地缴纳的费用
  • 什么情况下进项税额需要转出
  • 外派人员工资费用怎么算
  • 个体工商户是对公账户还是个人账户
  • 农产品收购发票可以跨区域开吗
  • 非税收入票据能报销吗
  • 可供出售金融资产会计处理
  • 营改增后如何纳税
  • 居民企业只就其境内全部所得纳税
  • 固定资产作为实收资本报废怎么处理
  • 小规模免了增值税怎么办
  • 最新房产税消息2020
  • 附加税没有计提会计分录
  • 企业没交社保年限怎么算
  • 年终奖的税收筹措是什么
  • 分公司注销时有未分配利润需要交税吗
  • 设备升级改造如何开发票
  • 利息支出企业所得税税前扣除标准
  • 企业分红给企业股东怎么交税
  • 个人垫付汽车修理怎么办
  • 鸿蒙系统开发者选项怎么关闭
  • 如果网页上有错字怎么办
  • 电脑更改工作组后进不了系统
  • 购买交易性金融资产时,支付的交易费用应计入
  • php创建表单
  • 公司被收购后所需资金
  • vantUI van-picker中的column使用,picker选择器展示对象数组里面的属性,自定义展示数据
  • php目录结构
  • 公司员工生病看望的红包能入公司账吗
  • 出差午餐补助公职出差
  • phpsubstr_replace
  • 基于php技术
  • php socket 非阻塞
  • 政府基金如何开立账户
  • vue初始化命令
  • 用友固定资产折旧方法
  • 结转成本费用的会计分录是什么?
  • phpcms怎么用
  • 购买电子承兑差额是多少
  • 税控盘全额抵扣发票怎么勾选
  • 公司的注册资本是什么意思
  • 所得税申报资产总额平均值
  • 太阳能发票图片
  • 销项100万进项80万交多少税
  • 收到员工生育津贴怎么做分录
  • 物业费没收到可以确认收入吗
  • 税率由16%变更为13怎么算
  • 免税 企业
  • 退回的个税手续费如何账务处理
  • 购入自用的机器怎么入账
  • sql删除查询结果
  • mysql存文章的字段设置为多大?
  • distinct 多个
  • win7下mysql6.x出现中文乱码的完美解决方法
  • windows7创建新桌面
  • Win7 64位旗舰版中让SSD固态硬盘更快的优化方法
  • 新买的读卡器不读卡,提示放入驱动盘
  • mac怎么连续播放视频
  • 虚拟机里安装centos7
  • Linux常用命令的实验总结
  • mac装xp系统
  • linux设置环境变量的命令
  • linux实用技巧
  • win7电脑无限蓝屏怎么解决
  • win8一直配置更新
  • 分形图形学
  • 表单提交servlet
  • bootstrap基础教程 源代码
  • node.js中的http.response.removeHeader方法使用说明
  • 高通 trinket
  • jquery 图片裁剪
  • 沧州地税局领导班子
  • 电子税务局季度利润表本月数
  • 红字专用发票进什么科目
  • 江苏省国家税务局电话号码
  • 电子税务局财务报表利润表本期金额
  • 安全生产管理局和应急局
  • 郑州市地方税务局新郑国际机场分局
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设