Python食谱-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中字符串对象是不可变的(immutable)。因此,任何对字符串的操作,包括字符串连接,都将生成新的字符串对象,而不是修改原有的字符串。连接N个字符串就会涉及到创建然后立即丢弃N-1个作为中间结果的字符串。因此,那些不产生中间结果而一次生成结果的操作的效率就会高得多。
Python的字符串格式化操作符%就是这种类型的操作,特别适合将几个字符串片段(每个都对应一个变量)和几个文本常量连接在一起的操作。对于这样的任务,效率并非最主要的收益。% 操作符带来其他一些好处比如:%比使用多个+连接符的代码更容易阅读,另外,无需对非字符串的对象(比如,数字)调用 str 函数转换类型,因为%s隐含了字符串类型转换。还有,你可以使用除%s之外的格式标识符,比如,你可以用格式标识符控制字符串形式的浮点数的显示位数。
什么是“序列”?
Python并没有称为“序列”的类型,但是在Python中序列是频繁使用的一个词。序列,严格意义上是指:一个可以每次一个的遍历访问其成员的容器对象,它支持索引,分割,并且能作为参数传递给内置函数len(len返回容器中的成员的数量)。Python的列表(list)是最经常用到的序列,除此之外还有:字符串,unicode对象,tuples,array.arrays,等等。
很多情况下我们并不要求对象能索引,分割,和可对其使用len, 而只要具有每次一个成员的遍历访问能力即可。这时我们称其为“可遍历对象”(iterable)。(或者对于有限个成员的情况,称之为“限界的可遍历对象”(bounded iterable))。是遍历对象但非序列的有:dictionary(遍历访问以任意顺序一次一个返回dictionary的key),file对象(遍历访问一次一行返回文件的文本内容),以及iterator,generator等等。任何可遍历对象都可以应用在for循环语句中或其他等价的环境中(比如:list comprehension的for子句,Python2.4的generator表达式,和许多内置函数比如:min,max,zip,sum,str.join,等等)
总结
如果一个序列中存在许多小的字符串片段,运行效率就会成为很重要的一个考量。对+或+=(或者等效但更机巧的内置函数reduce)实施循环操作所需的执行时间与要连接的字符个数之间为平方关系。幸运的是Python提供了一个非常出色的解决方法。字符串对象s的 join 方法,以一个序列的字符串作为其参数,返回一个用字符串s顺序连接序列中所有成员字符串的大字符串。比如: ''.join(pieces) 会将pieces中的成员连接在一起,不在其间插入任何字符。 ', '.join(pieces) 则会连接 pieces的所有成员并在其间插入逗号和空格。这是连接字符串最快速,最清晰,最优雅,也是可读性最强的方法。
如果pieces不是一次性提供的,而是逐个由输入或计算获得,我们可以使用list作为一个中间数据结构来存放pieces(要添加成员至list的末尾,可以调用list的extend或append的方法)。当获取pieces的list完成后,就可以使用 ''.join(thelist) 来将list中的所有成员连接成一个大的字符串。到目前为止在我给出的所有关于Python字符串操作的技巧中,我认为这个是最重要的一个。因为大多数Python程序运行太慢的原因可能就是用+或者+=来创建一个大字符串造成的。所以一定要有意识的避免那种用法,而采用我们推荐的 ''.join 的方法。
参见
Python函数库参考手册及Python in a Nutshell的关于字符串方法,字符串格式化操作,以及operator模块的章节














The voice of rtiaonialty! Good to hear from you.
XdTUAE pzmyqbocalmw