- Python
Python型変換まとめ|int・str・floatとValueError対処
Pythonの型変換とは、int() や str() などの組み込み関数に値を渡して、別の型の新しい値を作ることです。 文字列の "12" を数値の 12 にするなら int("12")、数値を文字列につなげるなら str(12) と書きます。変換できない値を渡すと ValueError か TypeError が発生します。
この記事では、8つの型の相互変換を「変換元×変換先」の早見表にまとめ、全セルに実行結果を付けました。 さらに "12.5"・"1,000"・全角数字・空文字・None など入力ごとに int() と float() が通るかどうかを一覧にし、ValueError: invalid literal for int() with base 10 の再現と直し方、安全に変換する safe_int 関数まで載せています。出力はすべて Python 3.11.15 で実行したものです。
Python型変換の早見表
変換元×変換先の一覧(全セル実行結果)
左の列の値を、上の行の関数に渡した結果です。TypeError・ValueError は例外が発生したことを表します。
| 変換元の値 | int() | float() | str() | bool() | list() | tuple() | set() | dict() |
|---|---|---|---|---|---|---|---|---|
int 5 |
5 |
5.0 |
'5' |
True |
TypeError | TypeError | TypeError | TypeError |
float 2.5 |
2 |
2.5 |
'2.5' |
True |
TypeError | TypeError | TypeError | TypeError |
str '12' |
12 |
12.0 |
'12' |
True |
['1', '2'] |
('1', '2') |
{'1', '2'} |
ValueError |
bool True |
1 |
1.0 |
'True' |
True |
TypeError | TypeError | TypeError | TypeError |
list [1, 2] |
TypeError | TypeError | '[1, 2]' |
True |
[1, 2] |
(1, 2) |
{1, 2} |
TypeError |
tuple (1, 2) |
TypeError | TypeError | '(1, 2)' |
True |
[1, 2] |
(1, 2) |
{1, 2} |
TypeError |
set {1, 2} |
TypeError | TypeError | '{1, 2}' |
True |
[1, 2] |
(1, 2) |
{1, 2} |
TypeError |
dict {'a': 1} |
TypeError | TypeError | "{'a': 1}" |
True |
['a'] |
('a',) |
{'a'} |
{'a': 1} |
この表から読み取れる要点は4つです。
- str() と bool() はどの型でも通る(例外にならない)
- int() と float() が受け取れるのは数値・文字列・bool。リストや辞書は TypeError
- list()・tuple()・set() が受け取れるのは「繰り返せる値」。文字列は1文字ずつに分かれ、辞書はキーだけになる
- dict() はキーと値のペアの並びが必要。[1, 2] のような単純なリストは TypeError
やりたいこと別の逆引き表
| やりたいこと | 書き方 | 結果 |
|---|---|---|
| 文字列を整数にする | int("12") |
12 |
| 文字列を小数にする | float("12.5") |
12.5 |
| 小数の文字列を整数にする | int(float("12.5")) |
12 |
| カンマ付きの文字列を整数にする | int("1,000".replace(",", "")) |
1000 |
| 16進数の文字列を整数にする | int("1F", 16) |
31 |
| 数値を文字列にする | str(123) |
'123' |
| 3桁区切りの文字列にする | f"{1234567:,}" |
'1,234,567' |
| 小数第2位までの文字列にする | f"{3.14159:.2f}" |
'3.14' |
| 0埋めの文字列にする | f"{5:03d}" |
'005' |
| 小数を四捨五入に近い形で整数にする | round(2.9) |
3 |
| 小数点以下を切り捨てる | int(2.9) |
2 |
| 文字列のリストを整数のリストにする | [int(s) for s in ["1", "2", "3"]] |
[1, 2, 3] |
| 数値のリストを1つの文字列にする | ",".join(map(str, [1, 2, 3])) |
'1,2,3' |
| 文字列を区切ってリストにする | "1,2,3".split(",") |
['1', '2', '3'] |
| リストの重複を除く(順番を保つ) | list(dict.fromkeys([3, 1, 3, 2])) |
[3, 1, 2] |
| 2つのリストから辞書を作る | dict(zip(["a", "b"], [1, 2])) |
{'a': 1, 'b': 2} |
| 辞書をキーと値のペアのリストにする | list({"a": 1, "b": 2}.items()) |
[('a', 1), ('b', 2)] |
| 型を調べる | type(12.5) |
<class 'float'> |
確認した環境と早見表を作ったコード
出力はすべて Python 3.11.15 で実行して得たものです。「12.5 を int() に渡した時のエラー文」「round(2.5)」「bool("False")」「全角数字の int()」の4点は Python 3.14.7 でも同じ結果になることを確かめました。それ以外の項目は 3.14 では未実行です。
早見表は次のコードで作りました。そのまま貼って実行できます。
vals = {"int": 5, "float": 2.5, "str": "12", "bool": True,
"list": [1, 2], "tuple": (1, 2), "set": {1, 2}, "dict": {"a": 1}}
funcs = [int, float, str, bool, list, tuple, set, dict]
for v in vals.values():
for f in funcs:
try:
r = repr(f(v))
except Exception as e:
r = f"{type(e).__name__}: {e}"
print(f"{f.__name__}({v!r}) -> {r}")
実行結果(例外が出た行を中心に抜粋):
list(5) -> TypeError: 'int' object is not iterable
dict(5) -> TypeError: 'int' object is not iterable
list(2.5) -> TypeError: 'float' object is not iterable
dict('12') -> ValueError: dictionary update sequence element #0 has length 1; 2 is required
list(True) -> TypeError: 'bool' object is not iterable
int([1, 2]) -> TypeError: int() argument must be a string, a bytes-like object or a real number, not 'list'
float([1, 2]) -> TypeError: float() argument must be a string or a real number, not 'list'
dict([1, 2]) -> TypeError: cannot convert dictionary update sequence element #0 to a sequence
int({'a': 1}) -> TypeError: int() argument must be a string, a bytes-like object or a real number, not 'dict'
list({'a': 1}) -> ['a']
ValueError は「型は合っているが中身が変換できない」、TypeError は「そもそもその型は受け取れない」 という違いがあります。エラー名を見れば、中身を整えるべきか、渡す値の型を見直すべきかが分かります。
文字列を数値にする:入力ごとの成功と例外の一覧
画面入力や CSV、設定ファイルから来る値は文字列です。よくある入力を int() と float() に渡した結果を一覧にしました。
| 入力 | int() | float() | メモ |
|---|---|---|---|
'12' |
12 |
12.0 |
基本形 |
'12.5' |
ValueError | 12.5 |
int() は小数点を読めない |
'1,000' |
ValueError | ValueError | カンマは先に取り除く |
'123'(全角) |
123 |
123.0 |
全角数字はそのまま通る |
'3.5'(全角) |
ValueError | 3.5 |
全角の小数も float() なら通る |
''(空文字) |
ValueError | ValueError | 空かどうかを先に確かめる |
None |
TypeError | TypeError | ValueError ではなく TypeError |
'1e3' |
ValueError | 1000.0 |
指数表記は float() だけ |
'0x1F' |
ValueError | ValueError | int('0x1F', 16) なら 31 |
' 42\n' |
42 |
42.0 |
前後の空白と改行は無視される |
'+7' / '-7' |
7 / -7 |
7.0 / -7.0 |
符号は付けてよい |
'1_000' |
1000 |
1000.0 |
アンダースコア区切りは通る |
'12a' |
ValueError | ValueError | 数字以外が混ざっている |
'inf' / 'nan' |
ValueError | inf / nan |
float() は特別な値として読む |
'一二三'(漢数字) |
ValueError | ValueError | 漢数字は対象外 |
True |
1 |
1.0 |
bool は int の一種 |
b'12'(bytes) |
12 |
12.0 |
bytes も受け取れる |
12.9 / -12.9(float) |
12 / -12 |
そのまま | 0 に近い方へ切り捨て |
実際のエラー文は次のとおりです。
int('12.5') -> ValueError: invalid literal for int() with base 10: '12.5'
int('1,000') -> ValueError: invalid literal for int() with base 10: '1,000'
float('1,000') -> ValueError: could not convert string to float: '1,000'
int('') -> ValueError: invalid literal for int() with base 10: ''
float('') -> ValueError: could not convert string to float: ''
int(None) -> TypeError: int() argument must be a string, a bytes-like object or a real number, not 'NoneType'
float(None) -> TypeError: float() argument must be a string or a real number, not 'NoneType'
int('1e3') -> ValueError: invalid literal for int() with base 10: '1e3'
int('0x1F') -> ValueError: invalid literal for int() with base 10: '0x1F'
意外に感じやすいのは、全角数字とアンダースコア区切りが通ること、前後の空白や改行が無視されることです。反対に、カンマ区切りと小数点は int() では読めません。
ValueError: invalid literal for int() with base 10 の再現と直し方
再現
age = int("12.5")
Traceback (most recent call last):
File "err1.py", line 1, in <module>
age = int("12.5")
^^^^^^^^^^^
ValueError: invalid literal for int() with base 10: '12.5'
(ファイルのパスは短く書き換えています。)
メッセージの読み方は次のとおりです。
| 部分 | 意味 |
|---|---|
| invalid literal for int() | int() が読める形の文字列ではない |
| with base 10 | 10進数として読もうとした |
| : '12.5' | 実際に渡された文字列。ここを見れば原因が分かる |
末尾のクォートの中身が原因を教えてくれます。空('')なら空文字、'1,000' ならカンマ、'12.5' なら小数点です。
原因別の直し方
| 末尾に表示される値 | 原因 | 直し方 | 結果 |
|---|---|---|---|
'12.5' |
小数点がある | int(float("12.5"))(切り捨て)または round(float("12.5")) |
12 |
'1,000' |
桁区切りのカンマ | int("1,000".replace(",", "")) |
1000 |
'' |
空文字(未入力) | int(s) if s else 0 のように既定値を決める |
0 |
'1e3' |
指数表記 | int(float("1e3")) |
1000 |
'0x1F' |
16進数の表記 | int("0x1F", 16) または int("0x1F", 0) |
31 |
'12a'、'abc' |
数字以外が混ざる | try / except で受け止め、入力し直してもらう | ― |
'1,000' |
全角のカンマ | NFKC 正規化のあとカンマを除く(後述) | 1000 |
None を渡した場合は ValueError ではなく TypeError になります。except ValueError だけでは受け止められないので、None の可能性があるなら先に if value is None で分けるか、except (ValueError, TypeError) と書きます。
try / except で受け止める基本形
rows = [
{"name": "ノート", "price": "1,200", "qty": "3"},
{"name": "ペン", "price": "", "qty": "十"},
]
for r in rows:
try:
total = int(r["price"].replace(",", "")) * int(r["qty"])
print(r["name"], total)
except ValueError as e:
print(r["name"], "-> 変換できません:", e)
実行結果:
ノート 3600
ペン -> 変換できません: invalid literal for int() with base 10: ''
変換は try の中に置き、except ValueError で受け止めるのが基本です。例外オブジェクトを as e で受け取ると、どの値で止まったかをそのままログに残せます。
基数を指定して2進数・16進数の文字列を変換する
int() の第2引数に基数(何進数として読むか)を渡します。
| 書き方 | 結果 | メモ |
|---|---|---|
int("1F", 16) |
31 |
16進数として読む |
int("0x1F", 16) |
31 |
0x の接頭辞が付いていてもよい |
int("101", 2) |
5 |
2進数 |
int("z", 36) |
35 |
36進数まで指定できる |
int("0x1F", 0) |
31 |
0 を渡すと接頭辞から自動で判断 |
int("0b101", 0) |
5 |
0b は2進数 |
int("0o17", 0) |
15 |
0o は8進数 |
int("010") |
10 |
基数を省くと先頭の0は無視 |
int("010", 0) |
ValueError | 基数0では先頭の0が曖昧として扱われる |
int(12.5, 10) |
TypeError | 基数を指定できるのは文字列だけ |
逆方向(整数から各進数の文字列へ)は次の関数を使います。
| 書き方 | 結果 |
|---|---|
hex(31) |
'0x1f' |
bin(5) |
'0b101' |
oct(15) |
'0o17' |
format(31, "x") |
'1f'(接頭辞なし) |
format(5, "08b") |
'00000101'(8桁に0埋め) |
全角数字とカンマ付きの文字列をそろえてから変換する
全角数字は int() がそのまま読めますが、全角のカンマや小数点、「円」などの文字が混ざると読めません。unicodedata.normalize("NFKC", ...) で全角の英数字と記号を半角にそろえると扱いやすくなります。
import unicodedata
text = "1,000円"
half = unicodedata.normalize("NFKC", text)
print(repr(half))
print(int(half.replace(",", "").replace("円", "")))
実行結果:
'1,000円'
1000
数字かどうかを事前に判定するメソッドには、次のような違いがあります。
| 式 | 結果 | メモ |
|---|---|---|
"12".isdigit() |
True |
|
"-12".isdigit() |
False |
符号があると False |
"12.5".isdigit() |
False |
小数点があると False |
"123".isdecimal() |
True |
全角数字も True |
"²".isdigit() |
True |
上付きの2も True になる |
"²".isdecimal() |
False |
|
int("²") |
ValueError | isdigit() が True でも int() は通らない |
"一".isnumeric() |
True |
漢数字も True(int() は通らない) |
isdigit() が True でも int() が通るとは限らず、負の数や小数は False になります。 事前判定で分岐するより、次の safe_int のように「変換してみて、例外なら既定値」という形のほうが確実です。
安全に変換するsafe_int関数(コピペ用)
変換できない時に例外で止めず、既定値を返す関数です。全角・空白・カンマ・"12.0" や "1e3" のような「整数として読める小数表記」にも対応しています。
import unicodedata
def safe_int(value, default=None):
"""int に変換できれば int を、できなければ default を返す。"""
if value is None or isinstance(value, bool):
return default
if isinstance(value, int):
return value
# 全角→半角、前後の空白、桁区切りのカンマをそろえる
text = unicodedata.normalize("NFKC", str(value)).strip().replace(",", "")
try:
return int(text)
except ValueError:
pass
try:
number = float(text) # "12.0" や "1e3" を拾う
except ValueError:
return default
return int(number) if number.is_integer() else default
def safe_float(value, default=None):
"""float に変換できれば float を、できなければ default を返す。"""
if value is None or isinstance(value, bool):
return default
text = unicodedata.normalize("NFKC", str(value)).strip().replace(",", "")
try:
number = float(text)
except ValueError:
return default
# nan と inf は「数として使えない」とみなす
return number if number == number and abs(number) != float("inf") else default
if __name__ == "__main__":
samples = ["12", " 42\n", "1,000", "123", "1,000", "12.0", "1e3",
"12.5", "", None, "abc", "0x1F", True, 7, 3.0, 3.7, "inf"]
for v in samples:
print(f"{v!r:10} -> safe_int: {safe_int(v)!r:5} safe_float: {safe_float(v)!r}")
print(safe_int("abc", default=0), safe_int("", default=-1))
実行結果(Python 3.11.15):
'12' -> safe_int: 12 safe_float: 12.0
' 42\n' -> safe_int: 42 safe_float: 42.0
'1,000' -> safe_int: 1000 safe_float: 1000.0
'123' -> safe_int: 123 safe_float: 123.0
'1,000' -> safe_int: 1000 safe_float: 1000.0
'12.0' -> safe_int: 12 safe_float: 12.0
'1e3' -> safe_int: 1000 safe_float: 1000.0
'12.5' -> safe_int: None safe_float: 12.5
'' -> safe_int: None safe_float: None
None -> safe_int: None safe_float: None
'abc' -> safe_int: None safe_float: None
'0x1F' -> safe_int: None safe_float: None
True -> safe_int: None safe_float: None
7 -> safe_int: 7 safe_float: 7.0
3.0 -> safe_int: 3 safe_float: 3.0
3.7 -> safe_int: None safe_float: 3.7
'inf' -> safe_int: None safe_float: None
0 -1
設計上の判断は次のとおりです。用途に合わせて調整してください。
| 判断 | この関数での扱い | 理由 |
|---|---|---|
| "12.5" や 3.7 | default を返す | 黙って切り捨てると、気づかないまま値が変わるため |
| True / False | default を返す | 1 / 0 に変換されると意図と違うことが多いため |
| "inf" / "nan" | default を返す | 計算に混ざると結果全体に影響するため |
| default の初期値 | None | 「0 が入力された」と「変換できなかった」を区別するため |
数値を文字列にする:str()とf文字列の書式
文字列と数値をつなぐ時のTypeError
print("合計: " + 100)
TypeError: can only concatenate str (not "int") to str
Python は文字列と数値を自動ではつなぎません。str() で文字列にするか、f文字列を使います。
| 書き方 | 結果 |
|---|---|
"合計: " + str(100) |
'合計: 100' |
f"合計: {100}" |
'合計: 100' |
"3" + "2" |
'32'(文字列の連結) |
int("3") + int("2") |
5(数値の足し算) |
"3" * 2 |
'33'(文字列のくり返し) |
"3" + 2 |
TypeError: can only concatenate str (not "int") to str |
3 + "2" |
TypeError: unsupported operand type(s) for +: 'int' and 'str' |
"3" + "2" は 5 ではなく "32" になります。 input() で受け取った値は文字列なので、計算する前に int() か float() を通します。
書式を指定して文字列にする
| 書き方 | 結果 | 用途 |
|---|---|---|
str(123) |
'123' |
そのまま |
str(1.0) |
'1.0' |
小数は .0 が付く |
f"{1234567:,}" |
'1,234,567' |
3桁区切り |
f"{3.14159:.2f}" |
'3.14' |
小数点以下2桁 |
f"{5:03d}" |
'005' |
0埋め3桁 |
str(5).zfill(3) |
'005' |
0埋め(文字列メソッド) |
f"{0.256:.1%}" |
'25.6%' |
パーセント表示 |
f"{255:x}" |
'ff' |
16進数 |
str(1e16) |
'1e+16' |
大きな小数は指数表記になる |
f"{1e16:.0f}" |
'10000000000000000' |
指数表記を避ける |
str(None) |
'None' |
None は文字列 'None' になる |
str([1, "a"]) |
"[1, 'a']" |
リストは表示用の形になる |
str(b"abc") |
"b'abc'" |
bytes は b"abc".decode() で 'abc' |
bytes を文字列にする時は str() ではなく decode() を使います。 str(b"abc") は "b'abc'" という表示用の文字列になるためです。
int()の切り捨てとround()の違い
小数を整数にする方法は複数あり、負の数と .5 の扱いが違います。
| 式 | 結果 | 動き |
|---|---|---|
int(2.9) |
2 |
0 に近い方へ切り捨て |
int(-2.9) |
-2 |
0 に近い方へ切り捨て |
math.trunc(-2.9) |
-2 |
int() と同じ |
math.floor(2.9) |
2 |
小さい方へ |
math.floor(-2.9) |
-3 |
小さい方へ(int() と違う) |
math.ceil(2.1) |
3 |
大きい方へ |
math.ceil(-2.9) |
-2 |
大きい方へ |
round(2.9) |
3 |
近い整数へ |
round(-2.9) |
-3 |
近い整数へ |
round(2.5) |
2 |
ちょうど半分は偶数側へ |
round(3.5) |
4 |
ちょうど半分は偶数側へ |
round(0.5) / round(1.5) |
0 / 2 |
ちょうど半分は偶数側へ |
round(2.675, 2) |
2.67 |
2.675 は内部では 2.675 よりわずかに小さい |
round(2.9, 0) |
3.0 |
桁数を渡すと float が返る |
int() は四捨五入ではなく切り捨てで、round() は「ちょうど半分」の時に偶数側へ丸めます。 round(2.5) が 2、round(3.5) が 4 になるのはこのためです。
学校で習う四捨五入(0.5 は常に切り上げ)をしたい時は decimal モジュールを使います。
from decimal import Decimal, ROUND_HALF_UP
print(int(Decimal("2.5").quantize(Decimal("1"), rounding=ROUND_HALF_UP)))
print(Decimal("2.675").quantize(Decimal("0.01"), rounding=ROUND_HALF_UP))
実行結果:
3
2.68
Decimal には文字列で値を渡すのがポイントです。float を直接渡すと、内部の誤差ごと取り込まれます。
| 式 | 結果 |
|---|---|
0.1 + 0.2 |
0.30000000000000004 |
Decimal("0.1") + Decimal("0.2") |
Decimal('0.3') |
Decimal(0.1) |
Decimal('0.1000000000000000055511151231257827021181583404541015625') |
Decimal(str(0.1)) |
Decimal('0.1') |
変換時に出るほかの例外も確認しました。
| 式 | 結果 |
|---|---|
int(float("inf")) |
OverflowError: cannot convert float infinity to integer |
int(float("nan")) |
ValueError: cannot convert float NaN to integer |
float(10**400) |
OverflowError: int too large to convert to float |
int("9" * 5000) |
ValueError: Exceeds the limit (4300 digits) for integer string conversion: value has 5000 digits; use sys.set_int_max_str_digits() to increase the limit |
最後の行のとおり、文字列と整数の相互変換には既定で 4300 桁の上限があります(sys.get_int_max_str_digits() の戻り値が 4300 でした)。
bool型への変換:bool("False")はTrueになる
bool() は「中身が空かどうか」で判定します。文字列の内容は見ません。
| 式 | 結果 | 理由 |
|---|---|---|
bool("False") |
True |
空でない文字列は True |
bool("false") |
True |
同上 |
bool("0") |
True |
同上 |
bool(" ") |
True |
空白1文字も「空でない」 |
bool("") |
False |
空文字 |
bool(0) / bool(0.0) |
False |
0 |
bool(-1) |
True |
0 以外の数 |
bool([]) / bool({}) |
False |
空のコンテナ |
bool([0]) |
True |
要素が1つある |
bool(None) |
False |
None |
int(True) / int(False) |
1 / 0 |
bool は int の一種 |
True + True |
2 |
足し算もできる |
str(True) |
'True' |
False になるのは 0、空文字、空のコンテナ、None だけと覚えておくと判断しやすくなります。
設定ファイルや環境変数の "False" を真偽値として読みたい時は、文字列の内容を比べる関数を用意します。
def to_bool(text):
t = str(text).strip().lower()
if t in ("true", "1", "yes", "on"):
return True
if t in ("false", "0", "no", "off", ""):
return False
raise ValueError(f"真偽値として読めません: {text!r}")
for v in ["True", "False", "false", " 0 ", "yes", "off", ""]:
print(f"{v!r:9} bool(): {bool(v)!s:5} to_bool(): {to_bool(v)}")
try:
to_bool("maybe")
except ValueError as e:
print("ValueError:", e)
実行結果:
'True' bool(): True to_bool(): True
'False' bool(): True to_bool(): False
'false' bool(): True to_bool(): False
' 0 ' bool(): True to_bool(): False
'yes' bool(): True to_bool(): True
'off' bool(): True to_bool(): False
'' bool(): False to_bool(): False
ValueError: 真偽値として読めません: 'maybe'
list・tuple・set・dictの相互変換
コンテナ同士の変換
| 書き方 | 結果 | メモ |
|---|---|---|
tuple([1, 2]) |
(1, 2) |
リスト→タプル |
list((1, 2)) |
[1, 2] |
タプル→リスト |
sorted(set([3, 1, 3, 2])) |
[1, 2, 3] |
重複を除いて並べる |
list(dict.fromkeys([3, 1, 3, 2])) |
[3, 1, 2] |
重複を除き、出現順を保つ |
list(range(3)) |
[0, 1, 2] |
range→リスト |
list({"a": 1, "b": 2}) |
['a', 'b'] |
辞書→キーのリスト |
list({"a": 1, "b": 2}.values()) |
[1, 2] |
辞書→値のリスト |
list({"a": 1, "b": 2}.items()) |
[('a', 1), ('b', 2)] |
辞書→ペアのリスト |
dict([("a", 1), ("b", 2)]) |
{'a': 1, 'b': 2} |
ペアのリスト→辞書 |
dict(zip(["a", "b"], [1, 2])) |
{'a': 1, 'b': 2} |
2つのリスト→辞書 |
dict(enumerate(["x", "y"])) |
{0: 'x', 1: 'y'} |
番号付きの辞書 |
dict(["ab", "cd"]) |
{'a': 'b', 'c': 'd'} |
2文字の文字列もペアとして読まれる |
dict([1, 2]) |
TypeError | ペアになっていない |
set([1, [2]]) |
TypeError: unhashable type: 'list' | set の要素にリストは入れられない |
list(5) |
TypeError: 'int' object is not iterable | 1要素のリストは [5] と書く |
set は順番を持たないため、set("aab") の表示順は実行のたびに変わることがあります(手元では {'b', 'a'} でした)。順番が大事な時は dict.fromkeys() か sorted() を使います。
文字列とリストの変換
| 書き方 | 結果 |
|---|---|
list("abc") |
['a', 'b', 'c'](1文字ずつ) |
"1,2,3".split(",") |
['1', '2', '3'] |
[int(s) for s in "1,2,3".split(",")] |
[1, 2, 3] |
list(map(int, ["1", "2", "3"])) |
[1, 2, 3] |
list(map(float, ["1", "2.5"])) |
[1.0, 2.5] |
",".join(["a", "b"]) |
'a,b' |
",".join([1, 2, 3]) |
TypeError: sequence item 0: expected str instance, int found |
",".join(map(str, [1, 2, 3])) |
'1,2,3' |
",".join(str(n) for n in [1, 2, 3]) |
'1,2,3' |
join() は文字列のリストだけを受け取ります。 数値のリストは map(str, ...) で文字列にしてから渡します。
「リストの形をした文字列」を元に戻す
str([1, 2, 3]) で作った文字列 "[1, 2, 3]" は、list() では元に戻りません(1文字ずつに分かれます)。用途に応じて次のどちらかを使います。
import ast
import json
print(json.dumps({"a": 1, "b": [1, 2], "c": None, "d": True}))
print(json.loads('{"a": 1, "b": [1, 2]}'))
print(ast.literal_eval("[1, 2, 3]"))
print(ast.literal_eval("{'a': 1}"))
実行結果:
{"a": 1, "b": [1, 2], "c": null, "d": true}
{'a': 1, 'b': [1, 2]}
[1, 2, 3]
{'a': 1}
| 手段 | 向いている場面 |
|---|---|
| json.dumps() / json.loads() | ファイル保存や API でのやり取り。None は null、True は true になる |
| ast.literal_eval() | Python の書き方(シングルクォートの辞書など)で書かれた文字列を値に戻す |
計算の中で自動的に起きる型変換
明示的に関数を呼ばなくても、数値同士の計算では型が変わります。
| 式 | 結果 | 型 |
|---|---|---|
1 + 1.0 |
2.0 |
float(int と float の計算は float) |
7 / 2 |
3.5 |
float |
3 / 1 |
3.0 |
float(割り切れても float) |
7 // 2 |
3 |
int |
2.9 // 1 |
2.0 |
float |
2 ** -1 |
0.5 |
float |
1 + True |
2 |
int |
/ の結果は常に float です。整数の結果が欲しい時は // を使うか、int() を通します。一方で、文字列と数値の間では自動変換は起きず、TypeError になります。
よくある質問
Q. input() で受け取った数字を足したら、つながった文字列になりました。
A. input() の戻り値は文字列です。"3" + "2" は "32" になります。int(input()) や float(input()) のように、計算の前に数値へ変換します。入力に数字以外が来る可能性があるなら、try / except ValueError で囲みます。
Q. int("12.5") がエラーになります。小数の文字列を整数にするには?
A. 一度 float にしてから int にします。int(float("12.5")) は 12(切り捨て)、round(float("12.5")) は 12(ちょうど半分は偶数側)です。0.5 を常に切り上げたい時は Decimal の ROUND_HALF_UP を使います。
Q. 変換する前に、数字かどうかを調べる方法はありますか? A. str.isdigit() や isdecimal() がありますが、"-12" や "12.5" は False になり、"²" のように isdigit() が True でも int() が通らない文字もあります。「try で変換して、except ValueError で既定値にする」形が確実です。この記事の safe_int をそのまま使えます。
Q. 型を確認するには?
A. type(値) で型が分かり、isinstance(値, int) で判定できます。なお isinstance(True, int) は True になります(bool は int の一種のため)。
まとめ
- str() と bool() はどの型でも通り、int() と float() は数値・文字列・bool だけ、list()・tuple()・set() は繰り返せる値だけを受け取る
- ValueError は中身が読めない、TypeError は型が受け取れない。 None を渡した時は TypeError になる
- ValueError: invalid literal for int() with base 10 は末尾のクォートの中身を見る。 小数点は int(float())、カンマは replace()、空文字は既定値で対応する
- 全角数字・前後の空白・アンダースコア区切りは int() が読める。 カンマ・小数点・指数表記・0x 付きは読めない
- int() は切り捨て、round() はちょうど半分で偶数側へ。 常に切り上げたい時は Decimal と ROUND_HALF_UP
- bool("False") は True。 文字列の内容で判定したい時は to_bool のような関数を用意する
- 変換できない入力が来る箇所は、safe_int のように try / except と既定値で受け止める
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。