web-dev-qa-db-ja.com

文字列を連結する最もPython的な方法

この無害な小さなリストを考えると:

>>> lst = ['o','s','s','a','m','a']

私の目標は、次のいずれかの方法を使用して、小悪魔をpythonで連結することです。

A.仕事を完了するためのプレーンなol '文字列関数、短く、インポートなし

>>> ''.join(lst)
'ossama'

B.ラムダ、ラムダ、ラムダ

>>> reduce(lambda x, y: x + y, lst)
'ossama'

C.グローバリゼーション(何もせず、すべてをインポートする)

>>> import functools, operator
>>> functools.reduce(operator.add, lst)
'ossama'

この壮大なタスクを達成する他のPythonicの方法を提案してください。

簡潔な説明を与えて、ソリューションをランク付け(Pythonレベル)および評価してください。

この場合、最もPythonicなソリューションが最良のコーディングソリューションですか?

42
random guy

python最適化に関するGuidoの エッセイ をご覧ください。数値のリストを文字列に変換する方法について説明しています。goodそうしない理由は、joinの例を使用してください。

35
Dana the Sane
''.join(lst)

唯一のPython的な方法:

  • 明確です(すべての大きな男の子がすることと彼らが見ることを期待すること)、
  • シンプル(追加のインポートは不要、すべてのバージョンで安定)、
  • 高速(Cで記述)および
  • 簡潔(空の文字列でiterableの要素を結合!).
62
SilentGhost

もちろんjoinです。どうやって知るの?本当に愚かな方法でそれをしましょう:
問題が2つの文字列の追加のみであった場合は、おそらくstr1 + str2。それを次のレベルに上げるには何が必要ですか?直感的に、ほとんどの場合(私は思う)、sumを使用することになります。それがどうなるか見てみましょう:

In [1]: example = ['a', 'b', 'c']
In [2]: sum(example, '')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython console> in <module>()
TypeError: sum() can't sum strings [use ''.join(seq) instead]

うわー! Python何を使うべきか教えてくれました!:)

18
abyx

これが最もPython的でない方法です:

out = ""
for x in range(len(lst)):
  for y in range(len(lst)):
    if x + y == len(lst)-1:
        out = lst[y] + out
7
Eli

私自身は「結合」方法を使用していますが、python 2.6から、ほとんど使用されない基本型があります:bytearray)。

Bytearrayは非常に便利です。文字列を含む文字列の場合、Unicodeを使用するのが最善であるため、「結合」する方法が適しています。ただし、代わりにバイナリデータを処理する場合、バイト配列は両方とも使用できますPythonicおよびより効率的:

>>> lst = ['o','s','s','a','m','a']
>>> a = bytearray(lst)
>>> a
bytearray(b'ossama')
>>> print a
ossama

それは組み込みのデータ型です:インポートは必要ありません-その場合はそのまま使用してください-そして、最初にリストの代わりにバイト配列を使用できます-データのコピーがないため、「結合」よりも効率的です。バイト配列の文字列表現を取得します。

6
jsbueno

SilenGhost BUTからの素晴らしい回答ですが、提示されたreduceの「代替」についてほんの数語

[〜#〜] very [〜#〜]+またはoperator.add(最も頻度の高いもの、文字列の数が決まっているため、常にjoinを使用する必要があります。

+が2つの文字列を連結した新しい文字列を生成するからといって、joinが1つの最終文字列しか生成しない場合を除きます。したがって、3つの文字列があるとします。

A + B + C
-->
D = A + B
final = D + C

わかりました、それほど多くないようですが、D用にメモリを予約する必要があります。また、python文字列を使用するため、新しい中間文字列を生成するため、なんとなく高価です...

今、5本の弦で

A + B + C + D + E
-->
F = A + B
G = F + C
H = G + D
final = H + E

最良のシナリオ((A + B)+(C + D)+ Eを実行すると、メモリ上に3つの中間文字列が同時に存在することになります)を想定すると、3つの中間文字列が生成されます...新しいpythonオブジェクトを生成し、メモリ領域を予約し、メモリを数回解放します... Python関数を呼び出すオーバーヘッド(小さくはありません)

200の文字列で考えてみましょう。とんでもない多数の中間文字列になり、それぞれがpythonで完全なリストになるのにかなりの時間を費やし、多数のoperator.add関数を呼び出し、それぞれにオーバーヘッドがあります... reduce関数を使用しても、役に立ちません。これは別の方法で管理する必要がある問題です:join、これは[〜#〜] one [〜#〜]完全なpython文字列のみを生成します、最後のものであり、ONE python関数を呼び出します。

(もちろん、join、または配列のその他の類似した特殊な関数)

4
Khelben