Pythonのstring
は変更できないので、どうすればもっと効率的に文字列を連結できるかと考えていました。
私はそのように書くことができます。
s += stringfromelsewhere
のように、あるいはこのように
s = []
s.append(somestring)
later
s = ''.join(s)
この質問を書いているときに、このトピックについて語っている良い記事を見つけました。
http://www.skymind.com/~ocrow/python_string/
しかし、それはPython 2.xでの話なので、問題はPython 3で何か変わったのかということです。
たくさんの値を連結するのであれば、どちらともいえません。リストの追記はコストがかかります。それにはStringIOを使えばいい。特に多くの操作で構築している場合は。
from cStringIO import StringIO
# python3: from io import StringIO
buf = StringIO()
buf.write('foo')
buf.write('foo')
buf.write('foo')
buf.getvalue()
# 'foofoofoo'
すでに他の操作で完全なリストが返されている場合は、単に ''.join(aList)
を使用します。
python FAQより。多くの文字列を連結する最も効率的な方法は何ですか?。
ストリングスとバイトオブジェクトは不変です。 文字列を連結するのは効率が悪く、連結するたびに新しい オブジェクトが生成されるため、非効率です。一般的なケースでは、全体のランタイムコストは、文字列の長さの 文字列の長さの2乗になります。
多くのstrオブジェクトを蓄積するためには、推奨されるイディオムは リストにして、最後にstr.join()を呼び出すことです。
chunks = [] (チャンク) for s in my_strings: chunks = [] > for s in my_strings: > chunks.append(s) result = ''.join(chunks) となります。 (他にもio.StringIOを使うと効率的なイディオムです)
多数のバイトオブジェクトを蓄積するためには、推奨されるイディオムは バイト配列オブジェクトをインプレースコンカチネーション(+=演算子)で拡張することです。
result = bytearray() for b in my_bytes_objects: result += b
編集:私は愚かで、結果を逆に貼り付けていたので、リストへの追加が cStringIO よりも速いように見えました。また、bytearray/str concatのテストと、より大きなリストとより大きな文字列を使った2回目のテストも追加しました。(python 2.7.3)
大きな文字列のリストのためのipythonのテスト例。
try:
from cStringIO import StringIO
except:
from io import StringIO
source = ['foo']*1000
%%timeit buf = StringIO()
for i in source:
buf.write(i)
final = buf.getvalue()
# 1000 loops, best of 3: 1.27 ms per loop
%%timeit out = []
for i in source:
out.append(i)
final = ''.join(out)
# 1000 loops, best of 3: 9.89 ms per loop
%%timeit out = bytearray()
for i in source:
out += i
# 10000 loops, best of 3: 98.5 µs per loop
%%timeit out = ""
for i in source:
out += i
# 10000 loops, best of 3: 161 µs per loop
## Repeat the tests with a larger list, containing
## strings that are bigger than the small string caching
## done by the Python
source = ['foo']*1000
# cStringIO
# 10 loops, best of 3: 19.2 ms per loop
# list append and join
# 100 loops, best of 3: 144 ms per loop
# bytearray() +=
# 100 loops, best of 3: 3.8 ms per loop
# str() +=
# 100 loops, best of 3: 5.11 ms per loop
多少古いですが、Code Like a Pythonista: Idiomatic Pythonは +
よりも join()
を このセクションで推奨しています。また、PythonSpeedPerformanceTipsの文字列連結のセクションでは、以下のような免責事項があります。
このセクションの正確さは、Pythonの後のバージョンに関しては議論の余地があります。
このセクションの正確さは、Pythonの後のバージョンに関しては議論の余地があります。CPython 2.5 では、文字列の連結はかなり高速です。 CPython 2.5 では、文字列の連結はかなり高速ですが、他の Python 他の Python の実装には当てはまらないかもしれません。議論のために ConcatenationTestCode を参照してください。