web-dev-qa-db-ja.com

Python .joinまたは文字列連結

イテラブルがある場合は、_for x in y: str += x_ではなく常に.join(iterable)を使用する必要があることを理解しています。しかし、まだ反復可能ではない変数の数が決まっている場合、.join()を使用することはまだ推奨される方法ですか?

例えば私は持っています

_user = 'username'
Host = 'Host'
_

私はすべきですか

_ret = user + '@' + Host
_

または

_ret = '@'.join([user, Host])
_

どちらもかなり簡単なものになるので、パフォーマンスの観点からはあまり質問しません。しかし、私はここで人々が常に.join()を使用すると言っているのを読んだことがあり、そのための特別な理由があるのか​​、それとも.join()を使用するのが一般的に良いアイデアなのかと思っていました。

24
Falmarri

そのような文字列を作成している場合、通常は文字列フォーマットを使用します。

_>>> user = 'username'
>>> Host = 'Host'
>>> '%s@%s' % (user, Host)
'username@Host'
_

Python 2.6では、演算子のオーバーロードに依存せず、いくつかの追加機能を備えた別のフォームが追加されました。

_>>> '{0}@{1}'.format(user, Host)
'username@Host'
_

一般的なガイドラインとして、ほとんどの人は、2つの文字列をすぐに追加する場合にのみ、文字列に対して_+_を使用します。より多くの部分またはより複雑な文字列の場合は、上記のように文字列フォーマットを使用するか、要素をリストにアセンブルしてそれらを結合します(特に、ループの形式がある場合)。str.join()を使用する理由は、文字列を一緒に追加するということは、新しい文字列を作成する(そして古い文字列を破壊する可能性がある)追加ごとにを意味します。 Pythonはこれを最適化できる場合がありますが、str.join()はすぐに明確になり、より明白になり、大幅に速くなります。

29
Thomas Wouters

「これを実行しても大丈夫ですか?」

ret = user + '@' + Host

..そして答えはイエスです。まったく問題ありません。

もちろん、Pythonで実行できるクールな書式設定に注意する必要があります。長いリストの場合、「結合」が適切な方法ですが、このような単純な状況では、正解です。シンプルで明快で、パフォーマンスは問題になりません。

14
Nick Perkins

(文字列の書式設定を指しているすべての人が質問を完全に見逃していると確信しています。)

配列を作成して結合して文字列を作成するのは、パフォーマンス上の理由のみです。そのパフォーマンスが必要でない限り、またはそれがとにかくそれを実装する自然な方法である場合を除いて、単純な文字列連結ではなく、それを行うメリットはありません。

'@'.join([user, Host])と言っても直感的ではありません。それは私に不思議に思います:なぜ彼はこれをしているのですか?微妙な点はありますか? 「@」が複数ある場合はありますか?もちろん、答えはノーですが、自然な方法で書かれた場合よりも、結論に至るまでに時間がかかります。

文字列の連結を回避するためだけにコードを変形しないでください。本質的に問題はありません。配列の結合は単なる最適化です。

10
Glenn Maynard

Pythonの一般的なスタイルのPEP PEP-8スタイルガイドPythonコード

  • コードは、Pythonの他の実装(PyPy、Jython、IronPython、Pyrex、Psycoなど)を損なわない方法で作成する必要があります。たとえば、a + = bまたはa = a + bの形式のステートメントに対して、CPythonのインプレース文字列連結の効率的な実装に依存しないでください。これらのステートメントは、Jythonでは実行が遅くなります。ライブラリのパフォーマンスに敏感な部分では、代わりに '' .join()フォームを使用する必要があります。これにより、さまざまな実装間で連結が線形時間で行われることが保証されます。

これにより、効率が非常に重要な場合に、より自動的な習慣として習慣を維持できるように、結合を使用する習慣に変換しています。

だから私は私の投票に入れます:

ret = '@'.join([user, Host])
8
Matthew

私は次を使用します:

ret = '%s@%s' % (user, Host)
1
anti_social

2つの側面に基づいて、連結ではなくjoin()をお勧めします。

  1. もっと早く。
  2. よりエレガント。

最初の側面に関しては、ここに例があります:

import timeit    

s1 = "Flowers"    
s2 = "of"    
s3 = "War"    

def join_concat():    
    return s1 + " " + s2 + " " + s3  

def join_builtin():    
    return " ".join((s1, s2, s3))    

print("Join Concatenation: ", timeit.timeit(join_concat))         
print("Join Builtin:       ", timeit.timeit(join_builtin))

出力:

$ python3 join_test.py
Join Concatenation:  0.40386943198973313
Join Builtin:        0.2666833929979475

巨大なデータセット(数百万行)とその処理(1行あたり130ミリ秒)を考えると、多すぎます。

そして、第二の側面については、確かに、よりエレガントです。

0
ivanleoncz