商と余りを一度に求める
商と余りを一度に求める とは
divmod 関数で割り算の商と余りを同時に取得し、リストで返してみよう。本レッスンでは、商と余りを一度に求める の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。
divmod で 1 回の計算から 2 つの答えを得る
割り算をしたときに、商 と 余り の両方が欲しい場面はとても多いです。例えば、170 分 は 何時間 何分 か?、100 個 のリンゴを 7 人 で分けると 何個ずつ で 何個余る か? といった問題です。Python には、この 2 つを 1 回の呼び出しでまとめて返す 便利な組み込み関数 divmod が用意されています。
1 つの関数で複数の結果を返すパターンに、ここで初めて触れます。これは
Pythonの大きな特徴の 1 つです。
divmod の基本
divmod(a, b) は、a // b と a % b をまとめた (商, 余り) の タプル を返します。
Python
result = divmod(7, 3)
# result は (2, 1)
quotient, remainder = divmod(7, 3)
# quotient は 2, remainder は 12 行目のように、左辺に変数を , で並べることで、タプルを直接 2 つの変数に分けて受け取ることもできます。これを アンパック と呼びます。タプルを 1 つの値として扱うこともあれば、こうして分解することもできる、というのが Python の魅力です。
1 つの戻り値で複数の情報を返したい時、タプル + アンパックは
Pythonの定番イディオムです。
// と % の組み合わせとの違い
divmod(a, b) は内部的には (a // b, a % b) と同じ結果を返します。違いは「2 回計算するか、1 回で済ますか」と「コードの読みやすさ」です。
Python
# パターン 1 — 2 回計算
q = 100 // 7
r = 100 % 7
# パターン 2 — divmod で 1 回
q, r = divmod(100, 7)Python 内部では divmod の方が最適化されていて、特に大きな整数では // % を別々に計算するより速い、というメリットがあります。何より、コードの意図が「商と余りを一緒に欲しい」とはっきり伝わるのが大事です。
動きを追ってみる
divmod(170, 60) の処理を図で追うと、次のとおりです。
2 つの値が 1 つのタプルにまとめられて返ってきます。これを呼び出し側でアンパックすれば、hours, minutes = divmod(170, 60) のように 2 変数で受け取れます。実用的な計算で頻繁に出てくるパターンです。
戻り値の型に注意
Python 標準の divmod はタプル (2, 1) を返しますが、このレッスンの判定システムは JSON ベースで比較するので、タプルとリストは同じ並びの値として扱われます。意図を明示するため、このレッスンでは list(divmod(a, b)) でリスト化して返すか、return divmod(a, b) のままでも構いません。
Python
def quotient_and_remainder(a, b):
q, r = divmod(a, b)
return [q, r]上の書き方が、テストランナーで一番確実に通る形です。タプルとリストの違いは後の章で詳しくやりますが、今のところは「並びを表すのに 2 種類ある」と覚えておけば十分です。
よくある間違い
divmod で初学者がはまりやすいパターンは、次の通りです。
- 引数の順を逆にして
divmod(b, a)と書いてしまう - 戻り値を 1 つの変数で受けて、
(2, 1)のタプル全体が入って戸惑う - 0 で割って
ZeroDivisionError - 負の数で割ったときの余りの符号が直感と違う
特に最後の「負の数の余り」は要注意で、Python では -7 % 3 が 2 になります。これは数学的には正しいのですが、C や Java だと -1 になる場合があるので、他言語と行き来する人は混乱しがちです。
Python
print(divmod(-7, 3)) # (-3, 2)
print(divmod(7, -3)) # (-3, -2)「
Pythonの余りは常に divisor と同じ符号を持つ」と覚えておけば、もう迷いません。
やってみよう
このレッスンの課題は、整数 a と b を受け取り、a / b の商と余りを [商, 余り] のリストで返す quotient_and_remainder を実装することです。divmod を使えば 1 行で書けます。
Python
def quotient_and_remainder(a, b):
return list(divmod(a, b))または、// と % を別々に計算する書き方でも結果は同じです。
Python
def quotient_and_remainder(a, b):
return [a // b, a % b]どちらでも OK ですが、divmod を使った方が「商と余りをセットで欲しい」という意図が読み手に伝わります。これは些細なようでいて、ベテランエンジニアが大事にしている書き方の差です。
「同じ結果でも、意図が伝わる書き方を選ぶ」が、
Pythonらしさです。
商と余りを同時に扱う処理は、時間の換算、ページ分割、グルーピングなど、現場で本当に頻出します。今のうちに divmod を体に馴染ませておきましょう。
よくある質問
Q. このトピックは Python 以外の言語でも同じ書き方ですか?
A. 考え方は他言語と共通ですが、構文や標準ライブラリは異なります。Python はインデントでブロックを表し、コロン + 改行で構造を作るのが特徴です。他言語に移行する際は基本概念を維持しつつ、構文の差分を意識して書き換えると混乱が少ないです。
Q. 実行してエラーが出た場合の対処は?
A. エラーメッセージの最後の行(TypeError や NameError などの型)から原因と該当行を確認します。Python はトレースバックが下から上に読むと「呼び出し元 → 内部」の順で辿れます。print や IDE のデバッガで途中の変数を確認すると原因が見えてきます。
Q. 次のステップで何を学ぶべきですか?
A. 本レッスンの内容を理解できたら、本文の「やってみよう」を実装し、章末クイズに進むのがおすすめです。さらに自分のミニアプリ(電卓・todo・スコア集計など)に応用するとスキルが定着します。詰まったら本文の H2 セクションに戻って読み返してください。
次のレッスン
次は 複数の戻り値を返す で、divmod 関数で割り算の商と余りを同時に取得し、リストで返してみよう を学びます。
事前確認 — 進む前に次の 3 つができることを確認しましょう。
- divmod の要点を自分の言葉で説明できる
- このレッスンの最小コード (または操作手順) を見ずに書ける
- 練習問題やクイズで間違えた箇所を読み直して理解した
理解度チェック (30 秒)
Q. divmod とは何か、1 文で説明してください。
A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。
関連レッスン
要件
- 関数名は quotient_and_remainder、引数は a, b
- 戻り値は [商, 余り] のリスト
- divmod または // と % を使って計算する
入出力例
test-cases.txt
quotient_and_remainder(7, 3) → [2,1]
quotient_and_remainder(10, 2) → [5,0]
quotient_and_remainder(170, 60) → [2,50]
quotient_and_remainder(0, 5) → [0,0]