类似于 C # 中的 StringBuilder 的 Python 字符串类?

Python 中有类似于 C # 中 StringBuilder的字符串类吗?

185715 次浏览

你可以试试 StringIO或者 CStringIO

没有一对一的相关性。如果你想看一篇非常好的文章,请参阅 Python 中高效的字符串串联:

在 Python 中构建长字符串 程序设计语言有时可以 导致运行非常慢的代码 这篇文章我调查了 计算性能 字符串连接方法字符串连接方法。

TLDR 最快的方法如下,它非常紧凑,也很容易理解:

def method6():
return ''.join([`num` for num in xrange(loop_count)])

Python 有几个类似的功能:

  • 从片段构建大字符串的一种常见方法是生成一个字符串列表,并在完成后加入它。这是一个常用的 Python 习惯用法。
    • 要构建将数据与格式结合在一起的字符串,需要分别进行格式设置。
  • 对于字符级别的插入和删除,您将保留一个长度为1的字符串列表。(要使用字符串创建这个函数,需要调用 list(your_string)。您也可以使用 UserString.MutableString
  • (c)StringIO.StringIO对于本来可以接受文件的内容很有用,但是对于一般的字符串构建来说就不那么有用了。

我使用了 Oliver Crow 的代码(链接由 Andrew Hare 提供) ,并对其进行了一些调整,以适应 Python 2.7.3。(使用 timeit 包)。我在我的个人电脑上运行,联想 T61,6 GB 内存,Debian GNU/Linux 6.0.6(挤)。

下面是10,000次迭代的结果:

method1:  0.0538418292999 secs
process size 4800 kb
method2:  0.22602891922 secs
process size 4960 kb
method3:  0.0605459213257 secs
process size 4980 kb
method4:  0.0544030666351 secs
process size 5536 kb
method5:  0.0551080703735 secs
process size 5272 kb
method6:  0.0542731285095 secs
process size 5512 kb

对于5,000,000次迭代(方法2被忽略了,因为它运行得太慢了,就像永远一样) :

method1:  5.88603997231 secs
process size 37976 kb
method3:  8.40748500824 secs
process size 38024 kb
method4:  7.96380496025 secs
process size 321968 kb
method5:  8.03666186333 secs
process size 71720 kb
method6:  6.68192911148 secs
process size 38240 kb

很明显,Python 人员在优化字符串连接方面做得非常好,正如 Hoare 所说: “过早的优化是万恶之源”: -)

使用上面的方法5(伪文件) ,我们可以获得非常好的性能和灵活性

from cStringIO import StringIO


class StringBuilder:
_file_str = None


def __init__(self):
self._file_str = StringIO()


def Append(self, str):
self._file_str.write(str)


def __str__(self):
return self._file_str.getvalue()

现在正在使用它

sb = StringBuilder()


sb.Append("Hello\n")
sb.Append("World")


print sb

如果您在这里寻找 Python 中的快速字符串串联方法,那么您不需要特殊的 StringBuilder 类。简单的连接也可以很好地工作,没有 C # 中出现的性能损失。

resultString = ""


resultString += "Append 1"
resultString += "Append 2"

有关性能结果,请参见 Antoine-tran 的回答

依赖编译器优化是脆弱的。被接受的答案中的基准和安托万-特兰给出的数字是不可信的。Andrew Hare 犯了一个错误,在他的方法中包含了对 repr的调用。这同样减慢了所有方法的速度,但模糊了构造字符串的真正代价。

使用 join。它非常快,而且更加健壮。

$ ipython3
Python 3.5.1 (default, Mar  2 2016, 03:38:02)
IPython 4.1.2 -- An enhanced Interactive Python.


In [1]: values = [str(num) for num in range(int(1e3))]


In [2]: %%timeit
...: ''.join(values)
...:
100000 loops, best of 3: 7.37 µs per loop


In [3]: %%timeit
...: result = ''
...: for value in values:
...:     result += value
...:
10000 loops, best of 3: 82.8 µs per loop


In [4]: import io


In [5]: %%timeit
...: writer = io.StringIO()
...: for value in values:
...:     writer.write(value)
...: writer.getvalue()
...:
10000 loops, best of 3: 81.8 µs per loop

没有明确的类比-我认为你应该使用字符串串联(可能优化之前说)或第三方类(我怀疑他们是更有效的-列表在 python 是动态类型,所以没有快速工作的 char []缓冲区,因为我假设)。 类 StringBuilder 类的类并不是过早的优化,因为在许多语言中字符串的固有特性(不可变性)允许许多种优化(例如,为切片/子字符串引用相同的缓冲区)。 StringBuilder/stringbuffer/stringstream 类型的类比串联字符串(产生许多仍然需要分配和垃圾收集的小型临时对象)甚至类似于 printf 的字符串格式化工具工作得更快,不需要解释格式化模式开销,这对于大量的格式调用来说是相当消耗的。