web-dev-qa-db-ja.com

strオブジェクトとintオブジェクトを連結するにはどうすればよいですか?

次のことをしようとすると:

things = 5
print("You have " + things + " things.")

Python 3.xで次のエラーが表示されます。

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: must be str, not int

... Python 2.xの同様のエラー:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'int' objects

この問題を回避するにはどうすればよいですか?

58
Zero Piraeus

ここでの問題は、Pythonで+演算子に(少なくとも)2つの異なる意味があることです。数値型の場合、「数値を加算する」ことを意味します。

>>> 1 + 2
3
>>> 3.4 + 5.6
9.0

...シーケンス型の場合、「シーケンスを連結する」ことを意味します。

>>> [1, 2, 3] + [4, 5, 6]
[1, 2, 3, 4, 5, 6]
>>> 'abc' + 'def'
'abcdef'

原則として、Pythonはオブジェクトをあるタイプから別のタイプに暗黙的に変換しません。1 操作を「意味のある」ものにするために、それは混乱を招くためです。たとえば、'3' + 5'35'を意味するはずですが、他の誰かが8を意味すると考えるかもしれません。 '8'でも。

同様に、Pythonでは、2つの異なるタイプのシーケンスを連結できません。

>>> [7, 8, 9] + 'ghi'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "str") to list

このため、連結または追加のいずれを希望する場合でも、明示的に変換する必要があります。

>>> 'Total: ' + str(123)
'Total: 123'
>>> int('456') + 789
1245

ただし、より良い方法があります。使用するPythonのバージョンに応じて、3種類の文字列フォーマットが利用可能です2、複数の+操作を回避できるようにするだけでなく、

>>> things = 5
>>> 'You have %d things.' % things  # % interpolation
'You have 5 things.'
>>> 'You have {} things.'.format(things)  # str.format()
'You have 5 things.'
>>> f'You have {things} things.'  # f-string (since Python 3.6)
'You have 5 things.'

...ただし、値の表示方法を制御することもできます。

>>> value = 5
>>> sq_root = value ** 0.5
>>> sq_root
2.23606797749979
>>> 'The square root of %d is %.2f (roughly).' % (value, sq_root)
'The square root of 5 is 2.24 (roughly).'
>>> 'The square root of {v} is {sr:.2f} (roughly).'.format(v=value, sr=sq_root)
'The square root of 5 is 2.24 (roughly).'
>>> f'The square root of {value} is {sq_root:.2f} (roughly).'
'The square root of 5 is 2.24 (roughly).'

%補間str.format() 、または f-strings を使用するかどうかはあなた次第です:%補間は最も長くなりました(そして慣れ親しんでいます) C)のバックグラウンドを持つ人々、str.format()はより強力であることが多く、f-stringsはさらに強力です(ただし、Python 3.6以降でのみ使用可能です)。

別の代替方法は、printに複数の位置引数を指定した場合、sepキーワード引数(デフォルトは' ')を使用して文字列表現を結合するという事実を使用することです。

>>> things = 5
>>> print('you have', things, 'things.')
you have 5 things.
>>> print('you have', things, 'things.', sep=' ... ')
you have ... 5 ... things.

...しかし、それは通常、Pythonの組み込み文字列フォーマット機能を使用するほど柔軟ではありません。


1 数値型の場合は例外になりますが、ほとんどの人は「正しい」ことを行うことに同意します。

>>> 1 + 2.3
3.3
>>> 4.5 + (5.6+7j)
(10.1+7j)

2 実際には4 ... ... テンプレート文字列 はめったに使用されず、やや厄介です。

89
Zero Piraeus

TL; DR

  1. いずれか:print("You have " + str(things) + " things.")(旧式の方法)

  2. または:print("You have {} things.".format(things))(新しいPythonicおよび推奨される方法)


もう少し口頭で説明:
上記の優れた@Zero Piraeusの回答でカバーされていないものはありますが、私はそれを少し「縮小」しようとします
pythonの文字列と数字(種類は問わない)を連結することはできません。これらのオブジェクトには、相互に互換性のないplus(+)演算子の異なる定義があります(str case +は連結に使用され、数値の場合は2つの数値を加算するために使用されます)。オブジェクト間のこの「誤解」を解決するために:

  1. 古い方法では、str(anything)メソッドを使用して数値を文字列にキャストしてから、結果を別の文字列と連結します。
  2. よりPythonicで推奨される方法は、非常に用途の広い format メソッドを使用することです(Wordを使用する必要はありません。ドキュメントと this の記事を読んでください)

楽しんで、do@Zero Piraeusを読んで、きっとあなたの時間の価値があると答えてください!

8
John Moutafis

Python 2.x

  1. 'You have %d things.' % things [ 1 ]
  2. 'You have {} things.'.format(things) [ 2 ]

Python 3.6 +

  1. 'You have %d things.' % things [ 1 ]
  2. 'You have {} things.'.format(things) [ 2 ]
  3. f'You have {things} things.' []

参照

  1. printf-style String Formatting
  2. 組み込み型-> str.format
  3. フォーマットされた文字列リテラル
3
ngub05