【Python】型変換の使い方|int・str・float・bool・型の確認

【Python】型変換の使い方|int・str・float・bool・型の確認 Python

Pythonでは、文字列の"42"と数値の42は別の型(タイプ)として扱われます。たとえば入力フォームやファイルから読んだ値は文字列なので、計算するには数値へ型変換する必要があります。変換にはint()float()str()bool()といった関数を使います。

つまずきやすいのは、int("3.14")はエラーになること、int(3.9)は四捨五入ではなく切り捨てになること、そしてbool("False")Trueになることです。これらは知らないとバグの原因になります。この記事では、実機のPythonで確認しながら、型変換を整理します。

先に結論

  • 文字列→数値はint("42")float("3.14")、数値→文字列はstr(42)です。
  • int("3.14")はエラー。小数の文字列はint(float("3.14"))と二段階で変換します。
  • int(3.9)3。四捨五入ではなく、小数点以下を切り捨てます。
  • bool()では0""[]などがFalseになります。
  • bool("False")True。空でない文字列はすべてTrueです。
  • 型の確認はtype(x)isinstance(x, int)を使います。

変換前の文字列の整形は文字列メソッド(split・strip など)、数値を文字列に埋め込むならf-string、まとめて変換するならリストと組み合わせると便利です。

スポンサーリンク

文字列と数値の変換(int・float・str)

もっとも使うのが、文字列と数値の相互変換です。int()は整数、float()は小数、str()は文字列に変換します。

basic.py
# 文字列 → 数値
n = int("42")        # 42(整数)
f = float("3.14")    # 3.14(小数)
print(n + 1)         # 43(数値として計算できる)

# 数値 → 文字列
s = str(42)          # "42"
print(s + "歳")      # 42歳(文字列として連結できる)

# 整数 ⇔ 小数
print(float(3))      # 3.0
print(int(10))       # 10

実機でも、int("42")42になり、+ 1で計算できました。逆にstr(42)"42"になり、+ "歳"で文字列として連結できます。文字列と数値はそのまま足せない"42" + 1はエラー)ため、計算するなら数値へ、表示で連結するなら文字列へ、と目的に合わせて変換します。

int(“3.14”)はエラー(小数の文字列)

ここはよくハマる点です。int()小数の形の文字列"3.14")を渡すと、エラーになります。int()は「整数の文字列」しか受け付けないためです。

int-float-string.py
# NG: 小数の文字列を直接 int にできない
int("3.14")
# ValueError: invalid literal for int() with base 10: '3.14'

# OK: いったん float にしてから int にする
print(int(float("3.14")))   # 3

# 空文字や数字以外もエラーになる
# int("")      # ValueError
# int("abc")   # ValueError
小数の文字列は float を経由する

実機で確認したところ、int("3.14")ValueError: invalid literal for int() with base 10: '3.14'になりました。int()"42"のような整数の文字列しか変換できません。小数の文字列を整数にしたいときは、int(float("3.14"))のようにいったんfloat()で小数に変換してからint()にします。また、空文字""や数字以外の文字列"abc"ValueErrorになります。ユーザー入力など変換できない可能性がある値は、例外処理(try/except)で囲むか、次に紹介するisdigit()で事前に確認すると安全です。

int(3.9)は四捨五入ではなく切り捨て

もう1つの注意点です。int()に小数を渡すと、四捨五入ではなく、小数点以下を切り捨てます(正確には0の方向へ切り捨て)。四捨五入したいときはround()を使います。

truncate.py
print(int(3.9))     # 3(切り捨て・四捨五入ではない)
print(int(3.1))     # 3
print(int(-3.9))    # -3(0の方向へ切り捨て)

# 四捨五入したいなら round
print(round(3.9))   # 4
print(round(3.4))   # 3

実機でも、int(3.9)4ではなく3になりました。int()は小数点以下をそのまま捨てます。int(-3.9)-3になることから、「小さいほうへ」ではなく「0に近いほうへ」切り捨てると分かります。金額や個数を四捨五入したいならround()を使ってください。なおround()round(2.5)2になるなど、ちょうど0.5のときに最も近い偶数へ丸める仕様(いわゆる銀行丸め)の点にも注意します。

真偽値への変換 bool(とFalse扱いの値)

bool()は値をTrue/Falseに変換します。Pythonでは「空っぽ」や「ゼロ」を意味する値がFalseになります。これはif文の条件でもそのまま使われる考え方です。

bool.py
# False になる代表的な値
print(bool(0))      # False(数値の0)
print(bool(""))     # False(空文字)
print(bool([]))     # False(空リスト)
print(bool({}))     # False(空辞書)
print(bool(None))   # False(None)

# それ以外は True
print(bool(1))      # True
print(bool("a"))    # True
print(bool([0]))    # True(要素があれば中身に関係なくTrue)

実機でも、0""[]{}NoneはすべてFalseになりました。これらは「空・ゼロ・無し」を表す値です。逆に、それ以外の値はすべてTrueです。if my_list:のように書くと「リストが空でなければ」という意味になり、len(my_list) > 0と同じ判定ができます。

【最重要】bool(“False”)はTrue

もっとも注意したい落とし穴です。文字列の"False""0"bool()に渡すと、Trueになりますbool()は文字列の中身を読まず、「空文字かどうか」だけで判定するためです。

bool-string.py
# NG: 文字列の "False" は True になる!
print(bool("False"))   # True(空でない文字列はすべて True)
print(bool("0"))       # True("0" も中身があるので True)

# 空文字だけが False
print(bool(""))        # False

# 文字列を真偽値として判定したいなら、自分で比較する
answer = "True"
print(answer == "True")              # True
print(answer.lower() in ("true", "1", "yes"))   # True
文字列の “False” や “0” は True 扱い

実機で確認したところ、bool("False")bool("0")Trueになりました。bool()は文字列を「空かどうか」だけで判断し、中身が"False"でも"0"でも、空でなければTrueになります。設定ファイルや入力から読んだ"False"という文字列をbool()でそのまま判定すると、意図と逆の結果になります。文字列を真偽値として扱いたいときは、answer == "True"のように自分で比較するか、answer.lower() in ("true", "1", "yes")のように許容する値を決めて判定してください。

型を確認する type・isinstance

値が何の型かを調べるにはtype()、ある型かどうかを判定するにはisinstance()を使います。判定にはisinstance()のほうが向いています。

type-check.py
x = 42

print(type(x))              # <class 'int'>
print(type(x).__name__)     # int(名前だけ取り出す)

# 「int型かどうか」を判定する
print(isinstance(x, int))           # True
print(isinstance("a", str))         # True
print(isinstance(x, (int, float)))  # True(複数の型のどれか)

# 注意: bool は int の一種
print(isinstance(True, int))        # True
型判定は isinstance が基本

型を判定するときは、type(x) == intよりもisinstance(x, int)が推奨されます。isinstance()は継承関係も考慮し、複数の型をisinstance(x, (int, float))のようにまとめて判定できるためです。なお実機で確認したところ、isinstance(True, int)Trueになります。これはPythonでは真偽値(bool)が整数(int)の一種として扱われ、True1False0として計算できるためです。数値だけを厳密に判定したい場面では、この点に気をつけてください。

変換できるか先に確かめる isdigit

文字列が数字だけでできているかは、isdigit()で確認できます。変換する前にチェックすれば、ValueErrorを避けられます。

isdigit.py
print("123".isdigit())    # True
print("abc".isdigit())    # False
print("-1".isdigit())     # False(マイナス記号は数字ではない)
print("3.14".isdigit())   # False(小数点は数字ではない)

# 変換前にチェックする
s = "123"
if s.isdigit():
    print(int(s))         # 123
else:
    print("数値に変換できません")

実機でも、"123".isdigit()True"-1""3.14"Falseになりました。isdigit()0〜9の数字だけTrueとするため、マイナス記号や小数点が含まれるとFalseになります。マイナスや小数も許容したい場合は、isdigit()では不十分なので、try/exceptで実際に変換を試すほうが確実です。

n進数の文字列を変換する(基数)

int()の第2引数に基数を渡すと、16進数や2進数の文字列を整数に変換できます。色コードやビット演算を扱うときに便利です。

base.py
print(int("ff", 16))     # 255(16進数として読む)
print(int("1010", 2))    # 10(2進数として読む)
print(int("777", 8))     # 511(8進数として読む)

# 逆に、整数を各表記の文字列にする
print(hex(255))   # '0xff'
print(bin(10))    # '0b1010'
print(oct(511))   # '0o777'

実機でも、int("ff", 16)255int("1010", 2)10になりました。第2引数で「何進数として読むか」を指定します。逆方向はhex()bin()oct()で、整数を16進数・2進数・8進数の文字列に変換できます。

リスト・タプル・集合の変換

並びを扱う型どうしも、list()tuple()set()で相互に変換できます。タプルや集合の性質を活かした変換がよく使われます。

collection.py
# リスト ⇔ タプル
print(tuple([1, 2, 3]))   # (1, 2, 3)
print(list((1, 2, 3)))    # [1, 2, 3]

# 集合に変換して重複を除去 → リストに戻す
print(list(set([1, 1, 2, 3])))   # [1, 2, 3]

# 文字列を1文字ずつのリストに
print(list("abc"))   # ['a', 'b', 'c']

実機でも、list(set([1,1,2,3]))で重複を除いた[1, 2, 3]が得られました。set()を経由する重複除去は定番です。list("abc")のように、文字列を1文字ずつのリストに分解することもできます。

よくある失敗

int(“3.14”)でエラーになる

int()は整数の文字列専用です。小数の文字列はint(float("3.14"))と二段階で変換します。

int(3.9)を四捨五入だと思い込む

int()は切り捨てです。四捨五入はround()を使います。

bool(“False”)をFalseだと思い込む

空でない文字列はすべてTrueです。answer == "True"のように自分で比較します。

文字列と数値をそのまま足す

"42" + 1はエラーです。計算ならint()、連結ならstr()でそろえます。

変換できない入力をそのままintにする

ユーザー入力はisdigit()で確認するか、try/exceptで囲んでから変換します。

よくある質問

Qint(“3.14”)がエラーになります。
Aint()は整数の文字列しか変換できないため、小数の文字列を渡すとValueErrorになります。int(float("3.14"))のように、いったんfloat()で小数へ変換してからint()にしてください。結果は小数点以下が切り捨てられて3になります。
Qint()は四捨五入されますか?
Aいいえ。int()は小数点以下を切り捨てます(int(3.9)3)。0の方向への切り捨てなので、int(-3.9)-3です。四捨五入したいときはround()を使います。
Qbool(“False”)がTrueになります。
Abool()は文字列の中身ではなく「空かどうか」だけで判定するため、"False""0"でも空でなければTrueになります。文字列を真偽値として扱いたいときは、answer == "True"のように自分で比較してください。
Q値の型を調べるには?
Atype(x)で型そのもの、type(x).__name__で型名の文字列が得られます。「ある型かどうか」を判定したいときはisinstance(x, int)を使います。複数の型はisinstance(x, (int, float))のようにまとめて判定できます。
Q変換できる文字列か事前に確認するには?
A数字だけの文字列かはs.isdigit()で確認できます。ただしマイナスや小数点はFalseになるため、それらも許容したいときはtry/exceptで実際にint()float()を試し、失敗したら別の処理にするほうが確実です。

まとめ

  • 文字列→数値はint()float()、数値→文字列はstr()です。
  • int("3.14")はエラー。小数の文字列はint(float("3.14"))と二段階で。
  • int(3.9)は切り捨てで3。四捨五入はround()です。
  • bool()では0""[]などがFalse"False"True
  • 型の確認はtype()isinstance()、事前チェックはisdigit()です。

型変換はPythonの基礎ですが、int("3.14")のエラー、int(3.9)の切り捨て、bool("False")Trueになる3点は、知らないと必ずつまずくポイントです。ここを押さえておけば、入力データの処理で起きるバグの多くを未然に防げます。