連結に対して+が%sよりも優れているのはなぜですか?


88

Python %sではなく、文字列の連結に使用する必要があることを理解しています+

私は次のことができます:

hello = "hello"
world = "world"

print hello + " " + world
print "%s %s" % (hello, world)
print "{} {}".format(hello, world)
print ' '.join([hello, world])

しかし、なぜ私は以外のものを使用する必要があり+ますか?単純なを使用して連結を記述する方が簡単+です。次に、フォーマット文字列を見る場合%s%dandなどのタイプを指定します。型について明示する方が良いかもしれないことを理解しています。

しかし、それから私は、+連結のために使用することは、入力するのが簡単であっても避けるべきだと読みました。文字列を他の方法のいずれかで連結する必要があるという明確な理由はありますか?


29
誰がより良いと言ったのですか?
ヤニス

3
%sは連結用ではなく、Cから派生した文字列フォーマットの変換仕様ですprintf(3)。それまたは連結演算子を使用する場合があります。使用するものは、教義ではなく、状況の判断に基づいている必要があります。コードを書くのがどれほど簡単かは、一度だけ行うのでまったく関係ありません。
Blrfl

私はに疑問をリフォーカスしましたちょうど(私はPythonの人ではないよ、まだコードに不具合があるかもしれませんが)のpython。これが質問していることを確認し、適切な更新を行い、CまたはJavaに興味がある場合は別の質問をすることを検討してください。

12
そして今、私たちは優れたf弦を持っていますprint(f"{hello} {world}")、変数は文字列内で発生する場所で見られるため、連結の可読性があり、よりも高速ですstr.format
エンリコボルバ

回答:


88
  1. 読みやすさ。書式文字列の構文は、スタイルをデータから分離するため、読みやすくなります。また、Pythonでは、%s構文はすべての非strタイプを自動的に強制しstrます。連結のみで動作しますがstr、あなたが連結することはできませんstrint

  2. パフォーマンス。Python strでは不変なので、連結のペアごとに左右の文字列を新しい文字列にコピーする必要があります。長さ10の4つの文字列を連結すると、40だけではなく、(10 + 10)+((10 + 10)+10)+(((10 + 10)+10)+10)= 90文字がコピーされます文字。また、文字列の数とサイズが増えると、状況は二次的に悪化します。Javaは、一連の連結をuse StringBuilderに変換することにより、この場合を最適化しますが、CPythonはそうではありません。

  3. いくつかのユースケースでは、ロギングライブラリは、フォーマット文字列を使用してログエントリ文字列を遅延的に作成するAPIを提供します(logging.info("blah: %s", 4))。これは、ログライブラリが現在のログエントリをログフィルタによって破棄することを決定した場合にパフォーマンスを向上させるのに最適であり、文字列をフォーマットする必要はありません。


31
#1の科学的または経験的な情報源はありますか?私はそれがはるかだと思うので、かなり読みにくく(特に以上2か3の引数を持つ)
ロヴィス

4
@L.Möller:最終的に主観的な体験(読みやすさ)からどのようなソースを期待するのかよくわかりませんが、私の推論が必要な場合:1)%sにはプレースホルダーごとに2つの追加文字が必要です最小4(またはPEP8に従う場合は8、強制する場合は13)、2)%sは単一の文字列で囲まれているため、視覚的に解析しやすくなります。+を使用すると、文字列、演算子、変数を閉じることができます。 、演算子、オープン文字列、3)構文の色付け%sには、関数ごとに1つの色があります:文字列とプレースホルダ、+を使用すると、文字列、演算子、変数の色付けの3つの色付けが得られます。
ライライアン

4
@L.Möller:4)書式設定が必要な場所から離れて、変数または辞書に長い書式文字列を配置するオプションがあります。5)書式文字列は、構成ファイル、コマンド引数、またはデータベースからユーザー指定できます。 、連結でも同じことは言えません。しかし、ええ、補間する4〜5個以上の要素がある場合は%sも使用せず、代わりにPythonで%(varname)sバリアントまたは "{foo}"。format()を使用します。明示的な名前は、多くの補間された変数を持つ長いフォーマット文字列の読みやすさを改善すると思います。
ライライアン

2
何が「本当」かわからないので、証拠があるかどうか尋ねます:-)。本当に2番目のコメントに同意する
ロヴィス

6
#2が疑われる-証拠を文書化していますか?私はJavaにあまり精通していませんが、C#連結では文字列補間よりも高速です。私は#1に完全に同意し、どちらを使用するかを決定するために実際にそれを使用しますが、補間には、文字列の解析と複雑さが必要であり、連結にはそれが必要ないことを覚えておく必要があります。
ジミー・ホッファ

48

左から右に読むのは私だけですか?

私にとって、使うこと%sはドイツ語話者の話を聞くようなもので、非常に長い文が終わるまで動詞が何であるかを聞く必要があります。

これらのうち、一目でわかるものはどれですか?

"your %s is in the %s" % (object, location)

または

"your " + object + " is in the " + location  

17
明らかに、これは主観的です。最初のものがより読みやすく、書き込みや編集が簡単だからです。2つ目は、テキストをコードと混ぜて、両方を覆い、ノイズを追加します。たとえば、2番目のスペースを間違えるのは簡単です。
ジャックB

5
@JacquesB実際、あなたの脳はこのフォーマットに非常に精通しているので、すぐに括弧にジャンプして、即座に単語を置き換えていると思います。技術的には、左から右に読むことではありませんが、それはまったく問題ありません。私もそうだと思うので、はい、1は2番目の引用の前後に愚かな間隔の問題に対処する必要があることを知っているので読みやすく、それは本当に動作が遅いです。
ネルソン

3
n数十年後、私の心もそのように機能します;-)しかし、私はまだ私の答えを待っています。そして、それはあなたが持っているパラメーターが多いほど明らかになります。最後に、もしそれが一人の男のショーであるなら、あなたが馴染みのある、そして快適なもので行ってください。チームの努力であれば、一貫性とコードレビューを実施します。人々はどちらにも慣れることができます。
Mawg

4
最初のものは、文の中央にある「残骸」が少ないため、私にとって読みやすいです。私の目が最後まで一見するのは簡単です、それから私の脳は余分な引用符、スペース、プラスを解析するのが簡単です。もちろん、今ではPython 3.6形式の文字列を好んで使用しています f"your {object} is in the {location}"
ダスティンワイアット

8
また、変数自体を引用符で囲む必要がある場合は、読み書きがさらに難しくなります。 "your '" + object + "' is in the '" + location + "'"...私はその権利ちょうど今...得た場合でも、わからない
ダスティン・ワイアット

12

読みやすさの引数を明確にする例:

print 'id: ' + id + '; function: ' + function + '; method: ' + method + '; class: ' + class + ' -- total == ' + total

print 'id: %s; function: %s; method: %s; class: %s --total == %s' % \
   (id, function, method, class, total)

(2番目の例は読みやすいだけでなく、編集も簡単であることに注意してください。1行でテンプレートを変更し、別の行で変数のリストを変更できます)

別の問題は、%sコードも文字列に変換することです。そうしないと、%sコードよりも読みにくいstr()呼び出しを使用する必要があります。


1
私はあなたの最初の声明には同意しませんが、私たちは異なることに同意することができます、私はちょうどあなたの2番目の行に沿って答えを投稿しようとしていたので、賛成
-Mawg

6

使い方は+すべきではない、一般的には避けること。多くの場合、正しいアプローチです。%sまたはを使用するの.join()は特定の場合にのみ好ましく、通常、それらがより良い解決策である場合は明らかです。

この例では、3つの文字列を連結しています。使用する例+は明らかに最も単純で読みやすいため、お勧めです。

%sまたは、大きな文字列の途中.format()文字列または値を補間する場合に便利です。例:

print "Hello %s, welcome to the computer!" % name

この場合%s、最初の文字列を複数のセグメントに分割することを避けるため、これを使用すると読みやすくなります。特に、複数の値を補間する場合。

.join() 文字列の可変サイズシーケンスがある場合や、同じセパレータで複数の文字列を連結する場合に適しています。


2

単語の順序は異なる言語で変更される可能性があるため%s、ソフトウェアで文字列の翻訳を適切にサポートする場合は、with が必須です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.