def method2(): from UserString import MutableString out_str = MutableString() for num in xrange(loop_count): out_str += `num`return out_str
Python类库中包括一个MutableString类。根据其文档描述它主要用于教学目的(译注: "mutable string objects Python strings are immutable objects. This has the advantage, that strings may be used as dictionary keys. If this property isn't needed and you insist on changing string values in place instead, you may cheat and use MutableString. But the purpose of this class is an educational one: to prevent people from inventing their own mutable string class derived from UserString and than forget thereby to remove (override) the __hash__ method inherited from UserString. This would lead to errors that would be very hard to track down. A faster and better solution is to rewrite your program using lists.")。你可以能会以为在一个可变字符串上添加操作不会从分配或者拷贝字符串(译注:本来该类应该很像Java的StringBuilder的)。但是在测试中该方法比方法1还差。通过查看UserString.py的源代码我发现字符串在MutableString中的存储就是string,MutableString甚至都没重写__add__方法。所以使用该类对象合并字符串不会比一般的不可变字符串更快,实际上由于解释MutableString方法需要一些额外的开销会使得该方法更慢。 方法三:字符数组(Method 3: Character arrrays)
def method3(): from array import array char_array = array('c') for num in xrange(loop_count): char_array.fromstring(`num`)return char_array.tostring()
我几乎都没有尝试这种方法,但是邮件列表中有人提到了,所以我决定试试。该方法的思想就是用字符数组存储字符串。Python中的数组是可变的,所以它可以被原地改变(译注:也就是在该对象的那块内存上进行改变,而不需要通过复制到其他的空间上实现)而不需要拷贝现存的数组内容。这里我们对改变现存的数组元素没有兴趣。我们只是在数组末尾添加一些新的数组元素。fromstring()方法一个字符一个字符的添加字符串字符到字符数组对象中。 方法四:构造一个字符串列表,然后join它(Method 4: Build a list of strings, then join it)
def method4(): str_list = [] for num in xrange(loop_count): str_list.append(`num`)return ''.join(str_list)
这是一种通常被推荐的方法,因为它的字符串合并方法很Python。首先构造一个包含所有需要合并的字符串列表,然后使用一个字符串的join操作构造包含所有列表元素的字符串。
这人有点好玩,看看python习语的最后一行-我们在确定的空字符串上调用join方法。不是所有的语言都会让你在一个字面上的字符串调用方法(译注:这里的意识是’’是空字符串)。如果你觉得这儿有点不爽,你可以写成如下形式: string.join(str_list, '')。 方法五:写到一个伪文件中去(Method 5: Write to a pseudo file)
def method5(): from cStringIO import StringIO file_str = StringIO() for num in xrange(loop_count): file_str.write(`num`)return file_str.getvalue()
cStringIO模块提供的StringIO类可以像文件一样工作,但是它存储为一个字符串。很明显,添加内容到文件中是很容易的—你可以简单的写入到文件末尾,对StringIO类对象的操作也是一样。还有一个相似的模块叫StringIO, 不过它是以Python实现的,而cStringIO是用C实现的,所以cStringIO速度上会更快。使用cStringIO对象,我么可以构造一个每次写入一次内容的字符串,然后通过调用getvalue()方法收集其中的所有内容。
有意思的是,同python类似,在java中字符串也是不可变的对象。Java中有个类叫StringBuffer,它比python中的StringIO和数组方法都更加强大,因为它不仅支持添加字符串还支持插入和删除子字符串操作。 方法六:列表推导 (Method 6: List comprehensions)
def method6():return ''.join([`num` for num in xrange(loop_count)])