web-dev-qa-db-ja.com

「+」演算子なしの文字列連結

私はpythonで遊んでいましたが、値で使用しない限り、文字列を連結するために '+'演算子を使用する必要がないことに気付きました。

例えば:

string1 = 'Hello'   'World'  #1 works fine
string2 = 'Hello' + 'World'  #2 also works fine

string3 = 'Hello'
string4 = 'World'
string5 = string3   string4  #3 causes syntax error
string6 = string3 + string4  #4 works fine

今、2つの質問があります。

  1. ステートメント1が機能するのにステートメント3が機能しないのはなぜですか?
  2. ステートメント1と2の間に計算速度などの技術的な違いはありますか?
57
ibrahim

docs から:

複数の隣接する文字列リテラル(空白で区切られます)は、場合によっては異なる引用規則を使用して許可され、その意味は連結と同じです。したがって、「hello」「world」は「helloworld」と同等です。


次の理由により、ステートメント3は機能しません。

実行時に文字列式を連結するには、「+」演算子を使用する必要があります。

ドキュメントのサブヘッダーのタイトルも「文字列リテラル連結」であることに注意してください。これは文字列リテラルでのみ機能し、他のオブジェクトでは機能しません。


おそらく違いはありません。ある場合、それはおそらく非常に小さく、誰も心配する必要はありません。


また、これには危険があることを理解してください。

>>> def foo(bar, baz=None):
...     return bar
... 
>>> foo("bob"
... "bill")
'bobbill'

これは完璧な例ですエラーは黙って渡されるべきではありません。"bill"を引数bazにしたい場合はどうすればいいですか?コンマを忘れましたが、エラーは発生しません。代わりに、連結が行われました。

49
TerryA

+記号を使用するよりも効率的であるため、%sを使用できます。

>>> string2 = "%s %s" %('Hello', 'World')
>>> string2
'Hello World'

(または)


もう1つのメソッドは.formatです

>>> string2 = "{0} {1}".format("Hello", "World")
>>> string2
'Hello World'
>>> 
2
SuperNova

2番目の質問に答えるには:少なくとも違いはありません(少なくとも私が使用する実装では)。両方のステートメントを分解すると、それらはLOAD_CONST STORE_FASTとしてレンダリングされます。それらは同等です。

2
Hyperboreus

ステートメント3は、2つの文字列式を連結して新しい文字列を作成するときに「+」演算子が必要なため、機能しません。

一方、文字列1、2、および4の場合、空白で区切られた隣接するリテラルは、異なる引用規則を使用します。

また、これら2つの操作の実行に大きな時間差や顕著な時間差はありません。

%%timeit -n 1
s1='ab'
s2='ba'
print(s1+s2)

o/p最も遅い実行は、最も速い実行より17.08倍長くかかりました。これは、中間結果がキャッシュされていることを意味する場合があります。ループごとに57.8 µs±92.5 µs(7ランの平均±標準偏差、各1ループ)

%%timeit -n 1
s3='ab' 'ba'
print(s3)

o/p最も遅い実行は、最も速い実行よりも4.86倍長くかかりました。これは、中間結果がキャッシュされていることを意味する場合があります。ループあたり25.7 µs±21 µs(7ランの平均±標準偏差、各1ループ)

1
shray

これは、暗黙的な文字列リテラルの連結です。文字列リテラルでのみ発生し、変数または文字列に評価される他の式では発生しません。以前は(わずかな)パフォーマンスの違いがありましたが、最近では、ピープホールオプティマイザーはフォームを本質的に同等にする必要があります。

1
user2357112

ステートメント1が機能するのにステートメント3が機能しない理由

なぜなら、最初のステートメントでは、変数に定数を割り当てているからです。変数の割り当ては非常に単純なので、単一の変数に複数の定数を入れ続けることができ、割り当ては引き続き行われます。 "hello""world"という用語は、同じタイプの2つの定数です。だから、声明はうまくいきました。

以下を行うと、SyntaxErrorを取得します

string1 = "Hello" 1

その理由は、単一の変数割り当てで複数の定数を指定したためです。これはpythonを混乱させ、エラーとしてスローしました。

ステートメント3は、2つの変数に基づいた変数の割り当てに関するものです。これはpythonとしてSyntaxErrorを生成します。これは、変数に割り当てる前に2つの変数で何ができるかわかりません。

ステートメント1と2の間に計算速度などの技術的な違いはありますか?

はい。技術的な違いは、読みやすさだけではありません。読みやすさは、Pythonで最も重要です。訓練されていない目では、"hello" "world"はコンパイラが文字列にスペースを追加するように見えるかもしれません。そうではありません。

しかしながら、

"hello" + "world"

明示的かつ正常です。ほぼ常に、明示的は暗黙的よりも優れています。

0
thiruvenkadam