商と余りを一度に求める

生田 陸人
LuaGate エンジニア / 現役エンジニア
編集 LuaGate編集部

商と余りを一度に求める とは

divmod 関数で割り算の商と余りを同時に取得し、リストで返してみよう。本レッスンでは、商と余りを一度に求める の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。

divmod で 1 回の計算から 2 つの答えを得る

割り算をしたときに、余り の両方が欲しい場面はとても多いです。例えば、170 分何時間 何分 か?、100 個 のリンゴを 7 人 で分けると 何個ずつ何個余る か? といった問題です。Python には、この 2 つを 1 回の呼び出しでまとめて返す 便利な組み込み関数 divmod が用意されています。

1 つの関数で複数の結果を返すパターンに、ここで初めて触れます。これは Python の大きな特徴の 1 つです。

divmod の基本

divmod(a, b) は、a // ba % b をまとめた (商, 余り)タプル を返します。

Python

result = divmod(7, 3) # result は (2, 1) quotient, remainder = divmod(7, 3) # quotient は 2, remainder は 1

2 行目のように、左辺に変数を , で並べることで、タプルを直接 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) の処理を図で追うと、次のとおりです。

diagram (will load when visible)

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 % 32 になります。これは数学的には正しいのですが、CJava だと -1 になる場合があるので、他言語と行き来する人は混乱しがちです。

Python

print(divmod(-7, 3)) # (-3, 2) print(divmod(7, -3)) # (-3, -2)

Python の余りは常に divisor と同じ符号を持つ」と覚えておけば、もう迷いません。

やってみよう

このレッスンの課題は、整数 ab を受け取り、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 つができることを確認しましょう。

  1. divmod の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. divmod とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン

要件

  1. 関数名は quotient_and_remainder、引数は a, b
  2. 戻り値は [商, 余り] のリスト
  3. 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]

ヒント

main.py
main.py
学習モード

メモ

商と余りを一度に求める

⌘S で保存