数値型は2種類、真偽値は1種類
Pythonで普段使う数値型は int と float、そして真偽値を表す bool の3つです。普通のPythonプログラムで必要になる計算やロジックは、ほぼこれだけでカバーできます。
Pythonでは、実はbool型はintのサブタイプとして扱われていて、Trueの正体は1、Falseの正体は0です。この仕様は、あとで紹介するちょっとしたテクニックに活きてきます。
整数の算術演算
Pythonの整数(int)にはオーバーフローという概念がありません。普段はありがたみを感じないかもしれませんが、初めて階乗を計算する関数を書いてみると、そのありがたさが身に沁みます。他の多くの言語なら、とっくの昔に桁あふれして、こっそり負の数に化けているところです。
どちらも、どれだけ大きな数でも正確な答えを返します。上限になるのはメモリだけです。
算術演算子は想像どおりのものが揃っていますが、プラスアルファもあります。
上の表から、ぜひ覚えておきたいポイントが3つあります。
/は Python 3 では常に float を返します。両辺が整数でも同じです。10 / 2の結果は5ではなく5.0になります。整数が欲しい場合は//を使いましょう。//は負の無限大方向に丸められます。そのため-7 // 2は-3ではなく-4になります。最初は違和感がありますが、ルールとしては一貫しています。%は剰余を返します。「この数は偶数かな?」を判定する (n % 2 == 0) ときや、一定の範囲内でループさせたいときに重宝します。
浮動小数点の有名な落とし穴
float は仕様上、完璧ではありません。内部では2進数で表現されるため、ほとんどの小数を正確に表せないのです。よく引き合いに出される例がこちらです。
1行目の出力は 0.30000000000000004、2行目は False になります。これはPythonのバグではなく、IEEE 754規格に従う言語(Python、JavaScript、Java、Cなど)すべてに共通する挙動です。
実務上、ここから学べるポイントは2つあります。
- 浮動小数点同士を
==で比較しない。 「ほぼ等しい」で十分なら、math.isclose(a, b)を使うか、abs(a - b) < 許容誤差のように判定しましょう。 - お金の計算には
decimal.Decimalを使う。 標準ライブラリのdecimalモジュールを使えば、0.1 + 0.2のような落とし穴のない正確な十進演算ができます。floatより遅いのでデフォルトにはなっていませんが、通貨を扱うならこちらが正解です。
数値型どうしの変換
Pythonは、整数を文字列に、あるいは文字列を数値に勝手に変換してくれたりはしません。必要なら、自分で明示的に指示します。
変換できない値を渡すと ValueError が送出されます。
>>> int("hello")
ValueError: invalid literal for int() with base 10: 'hello'
エラーメッセージは素っ気ないですが、やるべきことははっきりしています。入力をきれいにするか、例外をキャッチするかのどちらかです。
python bool型をもう少し詳しく
真偽値は True と False の2つだけ。スペルは必ずこの通りで、先頭は大文字です。ほとんどの比較演算は、このどちらかを返します。
論理演算子は and、or、not の3つで、記号ではなく英単語としてそのまま書きます。
覚えておくと便利な小ネタをひとつ。and や or は必ずしも True や False を返すわけではなく、式の結果を決めた値そのものを返します。たとえば 0 or "fallback" は "fallback" を返し、5 and 10 は 10 を返します。おかげで name = user_input or "anonymous" のように、デフォルト値を手軽に書けるわけです。ただ、真偽判定の結果が想定外の型になって戸惑ったときのために、この挙動は頭に入れておきましょう。
python の truthy と falsy
Python では、if や while のような真偽値が求められる文脈で使うと、多くの値が「真っぽい(truthy)」「偽っぽい(falsy)」として扱われます。falsy として扱われるのは次の値です。
False0、0.0None- 空のコンテナ:
""、[]、{}、set()、()
これ以外はすべて truthy です。これを使えば、条件判定をより自然な書き方にできます。
if name: は「name に何か入っていれば」と読めばOKです。if name != "": よりずっとスッキリしますよね。ただし数値を扱うときは要注意で、if count: と書くと 0 は「スキップ」扱いになります。ほとんどのケースではそれで問題ないのですが、0 を有効な値として扱いたい場合は if count is not None: を使いましょう。
bool型で算術演算
Python の bool型は 実は 整数なので、そのまま算術演算に使えます。
このテクニックは意外と出番が多いので覚えておくと便利です。リストの中で条件を満たす要素が何個あるかを数えたいときは、boolを返すジェネレータをsum()に渡してあげればOKです。
実務で押さえておきたいポイント
intはオーバーフローしない。気にせずどんどん使ってOK。/の結果はfloatになる。整数で結果が欲しいときは切り捨て除算の//を使う。float同士を==で比較しないこと。許容誤差を持たせて比較するか、金額計算ならDecimalを使う。- truthy/falsyを活かすと条件式がすっきり読める。ただし
0や空文字列がfalsyになることは忘れずに。
次はinputとprint。この2つを覚えると、黙々と動くだけのスクリプトが、ユーザーとやり取りできるプログラムに変わります。
よくある質問
intとfloatの違いは何ですか?
intは小数点を持たない整数、floatは小数点付きの数値です。Pythonの整数はサイズ上限がなく、いくら大きくてもオーバーフローしません。一方floatはIEEE 754に従うため、10進数の計算でわずかな誤差が出ることがあります。
なぜ Python では 0.1 + 0.2 が 0.3 にならないのですか?
0.1 + 0.2 が 0.3 にならないのですか?2進数の浮動小数点では、ほとんどの10進小数を正確に表現できないためです。実際に0.1 + 0.2を評価すると0.30000000000000004になります。これはPython特有のバグではなく、IEEE 754を採用している言語すべてに共通する挙動です。厳密な10進演算が必要な場面ではdecimalモジュールを使いましょう。
truthy と falsy な値とは何ですか?
PythonではTrueやFalseそのものでなくても、真偽値の文脈で真・偽として扱われる値があります。0、空文字列、空のリスト、空の辞書、Noneなどはfalsy(偽)と判定され、それ以外はほぼtruthy(真)です。たとえばif my_list:は「リストの中身が空じゃなければ」と読めます。