大きな数を書くときに桁を数え間違えてしまうことは少なくありません。
Python 3.6以降では数値リテラルに_
(アンダースコア)を挟んで桁区切りを表現できます。
コードの可読性を上げながら計算結果や性能には影響しないのが特長です。
本記事では基本から注意点、PEP 8に沿った書き方まで丁寧に解説します。
Pythonの数値リテラルで_を桁区切りに使う
基本の書き方(例: 1_000_000)
Pythonでは数値リテラルの数字の間に_
を挟んで桁区切りを表現できます。
例えば1000000
は1_000_000
と書けます。
アンダースコアはあくまで読みやすさのためで、値はまったく同じです。
# 基本的な桁区切りの例
population = 1_000_000 # 1000000 と同じ
negative = -2_345_678 # 負の数でもOK
credit_card_mask = 1234_5678 # 4桁区切りの例(用途に応じて)
print(population, negative, credit_card_mask)
print(population == 1000000) # True: 値は同じ
1000000 -2345678 12345678
True
このように、アンダースコアは「数値の見た目」を整えるだけで、計算や比較の結果は通常の書き方と完全に一致します。
どのPythonバージョンで使える?(3.6+)
Python 3.6以降で数値リテラルの_
がサポートされました。
仕様はPEP 515で定義されています。
念のため、実行環境のバージョンは次のように確認できます。
import sys
print(sys.version)
print(sys.version_info >= (3, 6)) # 3.6以上なら True
3.13.6 (tags/v3.13.6:4e66535, Aug 6 2025, 14:36:00) [MSC v.1944 64 bit (AMD64)]
True
3.5以前では構文エラーになるため注意してください。
対応する数値の種類とサンプル
整数(int): 1_000_000
整数では、桁区切りを自由に挟めます。
日付のように意味単位で区切るのではなく、桁を読みやすくする目的で使用します。
n = 1_000_000
print(type(n), n)
<class 'int'> 1000000
浮動小数点(float): 1_234.56_78
小数点の前後どちらにもアンダースコアを置けます。
指数表記でも数字同士の間なら使えます。
x = 1_234.56_78 # 1234.5678
y = 1.23_45e3 # 1.2345 × 10^3 -> 1234.5
z = 6.02_2e2_3 # 6.022 × 10^23 を意識した例(指数部の数字間に _ を使用)
print(type(x), x)
print(type(y), y)
print(type(z), z)
<class 'float'> 1234.5678
<class 'float'> 1234.5
<class 'float'> 6.022e+23
小数点やe
の「直前直後」にアンダースコアは置けないという制約がある点は、このあと詳しく説明します。
2進数/8進数/16進数: 0b_1010_0110, 0o_755, 0x_FF_FF
基数接頭辞(0b, 0o, 0x)の直後にアンダースコアを置くことも可能です。
ビットやバイトのまとまりで区切ると読みやすくなります。
b = 0b_1010_0110 # 2進
o = 0o_755 # 8進(UNIXのパーミッション表記の読みやすさ向上)
h = 0x_FF_FF # 16進(バイト単位で区切り)
print(b, o, h)
print(bin(b), oct(o), hex(h))
166 493 65535
0b10100110 0o755 0xffff
複素数(complex): 1_000+2_500j
実部・虚部のそれぞれにアンダースコアを使えます。
虚数単位j
の直前に数字が連続する形で書きます。
z = 1_000 + 2_500j
print(type(z), z) # (1000+2500j)
print(z.real, z.imag) # 実部と虚部
<class 'complex'> (1000+2500j)
1000.0 2500.0
注意点と制限(エラーを避ける)
アンダースコアは「数字の間」だけで使えるという原則を押さえておくと、ほぼ全てのエラーを回避できます。
ここでは特にハマりやすいケースを具体的に示します。
先頭・末尾・連続の_は不可
数字の先頭や末尾、連続する__
は構文エラーになります。
# これはすべて構文エラー
num1 = _1000
SyntaxError: invalid decimal literal
num2 = 1000_
SyntaxError: invalid decimal literal
num3 = 1__000
SyntaxError: invalid decimal literal
数字の外側(例: 変数名の一部や演算子の隣)にアンダースコアを置くのも当然ながら誤りです。
小数点やe(指数)の直前直後の_は不可
小数点.
や指数記号e
/E
の直前直後にはアンダースコアを置けません。
一方で、数字同士の間ならOKです。
# OK 例: 数字の間にだけ _ を使っている
ok1 = 1_234.56_78
ok2 = 1.23_45e6
ok3 = 1e1_0 # 指数部の数字間に _
print(ok1, ok2, ok3)
1234.5678 1234500.0 10000000000.0
# NG 例: 小数点や e/E の直前・直後に _
ng1 = 1_.0
SyntaxError: invalid decimal literal
ng2 = 1._0
SyntaxError: invalid decimal literal
ng3 = 1e_10
SyntaxError: invalid decimal literal
ng4 = 1_e10
SyntaxError: invalid decimal literal
指数の符号+
/-
の直後にアンダースコアを置くのも不可です(例: 1e+_10
はNG)。
コード上の見やすさだけで、計算結果は同じ
アンダースコアはリテラルの見た目を良くするだけで、値や型、計算結果は一切変わりません。
初心者の方は、表示の見た目と内部の値を混同しないようにしましょう。
a = 1_000_000
b = 1000000
c = 1_234.56_78
d = 1234.5678
print(a == b, type(a), type(b))
print(c == d, type(c), type(d))
True <class 'int'> <class 'int'>
True <class 'float'> <class 'float'>
printすると_は表示されない(出力フォーマットとは別)
数値として扱う限りprint
の出力にアンダースコアは含まれません。
出力時に桁区切りを入れたい場合は、フォーマット機能を使います。
Python 3.6+ではf
-stringやstr.format
で_
や,
を区切り記号として選べます。
n = 1_000_000
# 素の出力(区切りなし)
print(n)
# アンダースコア区切りで表示
print(f"{n:_}") # -> 1_000_000
# コンマ区切り(会計など一般的な表記)
print(f"{n:,}") # -> 1,000,000
1000000
1_000_000
1,000,000
「リテラルの書き方」と「表示フォーマット」はまったく別物という点を押さえておくと混乱しません。
書き方のコツ(PEP 8に沿った桁区切り)
PEP 8は強制ではありませんが、チームで読みやすさを揃えるための実践的な指針が示されています。
アンダースコアの区切りも一貫性を大切にしましょう。
10進数は3桁ごとに区切る
金額や件数などの10進整数は、一般的な表記に合わせて3桁ごとに区切ると読みやすいです。
桁の取り違えを防げるため、ログや定数定義でも効果的です。
sales = 12_345_678
budget = 1_000_000_000
penalty = 50_000
print(sales, budget, penalty)
12345678 1000000000 50000
2/8/16進数はビットやバイト単位で区切る
進数によって読みやすい粒度が異なります。
バイナリは4ビット(ニブル)や8ビット(バイト)、16進は1バイト(2桁)または2バイト(4桁)、8進は3桁(権限表記など)で区切るのが定番です。
進数 | 推奨される区切り粒度 | 例 | コメント |
---|---|---|---|
2進(0b) | 4ビット/8ビット | 0b_1010_0110_1100 | ビットパターンが読み取りやすい |
8進(0o) | 3桁 | 0o_755 | UNIXパーミッションで見慣れた区切り |
16進(0x) | 2桁(=1B) or 4桁(=2B) | 0x_DE_AD_BE_EF, 0x_7F_FF | バイト境界やワード境界を意識 |
上表のように、「意味のある境界」で揃えると、デバッグやレビューが格段に楽になります。
プロジェクト内で表記を統一する
アンダースコアの区切り方は最終的にはチームの約束事です。
コーディング規約やレビューで「いつ、どの粒度で区切るか」を明文化すると、ファイルごとに表記がばらつくことを防げます。
自動整形ツール(例: Black)は数値の区切りを強制しませんが、リテラルの命名やコメントで補足したり、f"{n:_}"
などのフォーマット出力を統一することで、プロジェクト全体の可読性を高められます。
また、外部入力の文字列を数値化する場合はint()
やfloat()
が_
を含む文字列を受け付けない点に注意が必要です。
どうしても文字列内の区切りを許容したい場合はstr.replace("_", "")
などで取り除いてから変換するか、ast.literal_eval
で安全に評価する方法を検討してください。
import ast
raw = "1_000_000"
# int(raw) や float(raw) は ValueError になる(Python標準の仕様)
value_via_eval = ast.literal_eval(raw) # "Pythonの数値リテラル"として安全に評価
print(value_via_eval, type(value_via_eval))
1000000 <class 'int'>
ライブラリや設定ファイルで「文字列としての数値」に_
が許容されるとは限らないため、仕様の確認を忘れないようにしましょう。
まとめ
アンダースコアによる桁区切りは、見やすさを劇的に向上させる一方で、数値の意味や性能には影響しないという点が最大の利点です。
Python 3.6以降であれば整数・浮動小数点・2進/8進/16進・複素数のいずれでも利用でき、「数字の間だけ」「小数点やeの直前直後は不可」といったルールさえ守れば難しいことはありません。
10進では3桁区切り、2進/16進ではビットやバイト境界での区切りなど、PEP 8に沿った一貫した表記を心がけると、将来の自分やチームメイトが読み解くときの負担が大きく減ります。
また、出力時の見た目はf"{n:_}"
やf"{n:,}"
で制御できるため、「リテラルの表記」と「表示フォーマット」を分けて考えるのがコツです。
初心者の方も、日常的に_
を取り入れて可読性の高いコードを書く習慣を身につけていきましょう。