《Python Cookbook(第2版)中文版》——1.6 合并字符串

1.6 合并字符串

任务

有一些小的字符串,想把这些字符串合并成一个大字符串。
解决方案

要把一系列小字符串连接成一个大字符串,可以使用字符串操作符join。假如pieces是一个字符串列表,想把列表中所有的字符串按顺序拼接成一个大字符串,可以这么做:

largeString = ''.join(pieces)

如果想把存储在一些变量中的字符串片段拼接起来,那么使用字符串格式化操作符%会更好一些:

largeString = '%s%s something %s yet more' % (small1, small2, small3)

讨论

Python中,+操作符也能够将字符串拼接起来,从而实现类似的功能。假如有一些保存在变量中的字符串片段,使用下面这种代码似乎是一种很自然的方式:

largeString = small1 + small2 + ' something ' + small3 + ' yet more'

类似地,如果有一个小字符串序列,假设叫做pieces,那么很自然地,可以像这样编写代码:

largeString = ''
for piece in pieces:
      largeString += piece

或者,用完全等同但却更加漂亮和紧凑的方式:

import operator
largeString = reduce(operator.add, pieces, '')

不过,不要认为上述例子中给出的方法已经足够好了,上面给出的方法都有许多值得推敲的地方。

Python中的字符串对象是无法改变的。任何对字符串的操作,包括字符串拼接,都将产生一个新的字符串对象,而不是修改原有的对象。因此拼接N个字符串将涉及创建并丢弃N-1个中间结果。当然,不创建中间结果的操作会有更佳的性能,但往往不能一步到位地取得最终结果。

如果有少量字符串(尤其是那些绑定到变量上的)需要拼接,甚至有时还需要添加一些额外的信息,Python的字符串格式化操作符%通常是更好的选择。性能对这种操作完全不是一个问题。和使用多个+操作符相比,%操作符还有一些其他的潜在优点。一旦习惯了它,%也会让你的代码的可读性更好。也无须再对所有的非字符串(如数字)部分调用str,因为格式指定符%s已经暗中做完了这些工作。另一个优点是,还可以使用除%s之外的其他格式指定符,这样可以实现更多的格式要求,比如将浮点数转化为字符串的表示时,可以控制它的有效位数。

什么是“序列”? Python并没有一个特别的类型叫做sequence,但序列是Python中一个非常常用的术语。序列,严格地讲,是一个可以迭代的容器,可以从中取出一定数目的子项,也可以一次取出一个,而且它还支持索引、切片,还可以传递给内建函数len(返回容器中子项的数目)。Python的list就是“序列”,你已经见过多次了,但还有很多其他的“序列”(string、unicode对象、tuple、array.array等)。 通常,一个对象即使不支持索引、切片和len。只要具有一次获得一项的迭代能力,对应用而言就已经够用了。这叫做可迭代对象(或者,如果我们把范围限定在拥有有限子项的情况下,那就叫做有边界可迭代对象)。可迭代对象不是序列,而是如字典(迭代操作将以任意顺序每次取得一个key)、文件对象(迭代操作将给出文本文件的行数)等,还有其他一些,包括迭代器和生成器等。任何可迭代对象都能用在for循环语句以及一些等价的环境中(Python 2.4的生成器表达式、列表推导中的for子句、以及很多内建的方法,比如min、max、zip、sum、str.join等)。 在http://www.python.org/moin/PythonGlossary ,可以发现一个词汇表,Python Glossary,它能够帮助你了解很多术语。虽然本书的编辑尽量严格按照那个词汇表的描述来使用术语,仍可能发现本书在很多地方提到了序列、可迭代对象、甚至列表,实际上,严格地讲,我们都应该指明为有边界的可迭代对象。比如,在本节的开头,我们说“一个小字符串的序列”,实际上那是一个有边界的字符串的可迭代对象。在全书使用“有边界的可迭代对象”这样的术语给人的感觉像是在读一本数学书,而不是一本实践性很强的编程书!所以我们决定采用略微偏离严格术语系统的词,这样有助于获得更好的可读性,同时也能够更好地体现本书的多元化。最后结果还不错,根据上下文环境,那些不怎么严密的术语的真实含义仍然能够被清晰地表达出来。

当一个序列中包含了很多的小字符串的时候,性能就变成了一个很现实的问题。在内部使用了+或者+=(和内建函数reduce作用相同,但是更漂亮)的循环所需要的时间跟需要累加的字符数的平方成正比,因为分配空间并填充一个大字符串所需要的时间大致正比于该字符串的长度。幸好Python提供了另一个更好的选择。对于字符串对象s的join方法,我们可以传入一个字符串序列作为其参数,它将返回一个由字符串序列中所有子项字符串拼接而成的大字符串,而且这个过程中只使用了一个s的拷贝用于串接所有的子项。举个例子,".join(pieces)把pieces中所有的子项一口吞下,而无须产生子项之间的中间结果,再比如,', '.join(pieces)拼接了所有的子项字符串,并在邻接的两项之间插入了一个逗号和空格。这是一种快速、整洁、优雅且兼具良好可读性的合并大字符串的方法。

但有时并不是所有的数据在一开始就已经就位,比如数据可能来自于输入或计算,这时可以使用一个list作为中间数据结构来容纳它们(可以使用list的append或extend方法在末尾添加新的数据)。在取得了所有的数据之后,再调用".join(thelist)就可以得到合并之后的大字符串。在我能教给你的Python的字符串处理的各种技巧和方法中,这是最重要的一条:很多Python程序效能低下的原因是由于它们使用了+和+=来创建大字符串。因此,一定要提醒自己永远不要使用那种做法,而应该使用本节推荐的".join方法。

Python 2.4在这个问题的改善上做了很多工作,在Python 2.4中使用+=,性能损失要比以前的版本小一些。但".join仍然要快许多,而且在各方面都更具优势,至少对于新人和粗心的开发人员来讲,它消耗的时钟周期也更少。类似地,psyco(一种特制的just-in-time[JIT] Python编译器,请查看http://psyco.sourceforge.net/ )能更大幅度地减少+=带来的性能损失。不过,我还是要强调,’’.join依然是最值得选择的方式。

时间: 2024-10-27 09:12:41

《Python Cookbook(第2版)中文版》——1.6 合并字符串的相关文章

《像计算机科学家一样思考Python(第2版)》——2.6 字符串操作

2.6 字符串操作 通常来说,字符串不能进行数学操作.即使看起来像数字也不行.下面的操作是非法的: '2' - '1' 'eggs'/'easy' 'third'*'a charm' 但有两个例外:+和*. 操作符+进行字符串拼接(string concatenation)操作,意即将前后两个字符首尾连接起来.例如: >>> first = 'throat' >>> second = 'warbler' >>> first + second throa

《Python Cookbook(第2版)中文版》——第1章 文本 1.1 每次处理一个字符

第1章 文本 引言 感谢:Fred L. Drake, Jr.,PythonLabs 对于脚本语言来说,文本处理任务构成了一个重要的组成部分,每个人都会同意文本处理非常有用.每个人都会有一些文本需要重新格式化或者转化为另一种形式.问题是,每个程序都与另一个程序有点不同,无论它们是多么相似,想提取出一些可复用的代码片段并用它来处理不同的文件格式仍然是非常困难的. 什么是文本 看起来问题有点简单得过分了,事实上,我们看到了文本,就知道了什么是文本,文本是一串字符,这正是它与二进制数据之间的不同.二进

《Python Cookbook(第2版)中文版》——导读

前 言 这本书不是一本典型的O'Reilly风格的书,而是一本集合了多个作者的手稿的作品.实际上,这也是一种将开源开发的方式应用到书籍出版业的尝试.Python社区有超过300个成员在本书中贡献了他们的心得和资料.在这里,我们作为编辑,想给你--本书的读者,介绍一些重要的背景资料,这些背景资料是关于此书是如何编著出来,以及这个过程和涉及的人,并提出一些关于这种崭新的风格的思考. 目 录 [第1章 文本1.1 每次处理一个字符](https://yq.aliyun.com/articles/963

《Python Cookbook(第2版)中文版》——1.17 替换字符串中的子串—Python 2.4

1.17 替换字符串中的子串-Python 2.4 任务 在Python 2.4的环境下,你想完成这样的任务:给定一个字符串,通过查询一个字符串替换字典,将字符串中被标记的子字符串替换掉. 解决方案 Python 2.4提供了一个新的string.Template类,可以应用于这个任务.下面给出一段代码以展示怎样使用这个类: import string # 从字符串生成模板,其中标识符被$标记 new_style = string.Template('this is $thing') # 给模板

谁有<<CLR Via C#>>第三版中文版的电子书

问题描述 谁有<<CLRViaC#>>第三版中文版的电子书,我是个初学者,看网上推荐此书的人多,想看一下,我的QQ:330784617.谢谢!! 解决方案 解决方案二:试一试我一般看英文的,虽然很少看书:(解决方案三: 解决方案四:第二版有的,想看第三版.

拒绝从入门到放弃_《Python 核心编程 (第二版)》必读目录

目录 目录 关于这本书 必看知识点 最后 关于这本书 <Python 核心编程 (第二版)>是一本 Python 编程的入门书,分为 Python 核心(其实并不核心,应该叫基础) 和 高级主题 两大部分,以 Python 2.x 作为主要演示版本,涵盖的知识面广,知识点较齐全,代码多且好理解,但对 Python 版本特性的内容太久远,不合时宜. 整体来说 Python 核心 部分是主要内容,高级主题 部分作为应用扩展内容.后半部分篇幅较短,内容不够深入,只到了解的层面,好在横向够广(每一个主

(六十二)第四章总结——《C++ Primer Plus 第6版 中文版》

书是<C++ Primer Plus  第6版  中文版> 数组.指针.结构 是C++的3种复合类型.   注:为了方便,类型名用int为主,变量名用a为主.   数组: 包括数组(例如int a[10];)和字符串(例如char a[10];),还有string类(例如string a="abc";),vector类(例如vector<int>a(5)).array类(array<int,3>a)等. 数组名表示数组所在的(第一个元素)内存地址.

求大神解答一下-C++ primer plus 第6版 中文版 第16章复习题的一个问题

问题描述 C++ primer plus 第6版 中文版 第16章复习题的一个问题 奇葩的是课后居然没答案...... 求正规.严谨.简洁的标准答案! 程序清单16.15(在p708页):functor.cpp //functor.cpp--using a functor #include尖括号iostream尖括号 #include尖括号list尖括号 #include尖括号iterator尖括号 #include尖括号algorithm尖括号 template//functor class

【转】c++.primer.plus.第五版.中文版[下载]

c++.primer.plus.第五版.中文版[下载] 一共有5部分.全部下载完才可解压阅读. c++.primer.plus.第五版.中文版(一) c++.primer.plus.第五版.中文版(二) c++.primer.plus.第五版.中文版(三) c++.primer.plus.第五版.中文版(四) c++.primer.plus.第五版.中文版(五) "在遇到无法解决的问题时,我总会求助于C++ Primer一书."--Bruce Eckel,"编程思想"