Pythonのdivmod()関数を徹底解説!商と剰余を同時に取得
Pythonで割り算を行う際、結果として得られる「商」と「余り(剰余)」の両方が同時に必要な場面は意外と多くあります。例えば、時間の単位変換(秒から分と秒へ)、ページング処理での現在のページと残りアイテム数、あるいは巡回セールスマン問題のようなアルゴリズムの実装などです。このような場合に便利なのが、Pythonの組み込み関数である**divmod()関数**です。この記事では、divmod()関数の基本的な使い方から、その効率性、そして具体的な活用事例までを初心者にもわかりやすく解説します。
divmod()関数とは?Pythonにおける商と剰余の同時取得
Pythonのdivmod()関数は、2つの数値aとbを引数に取り、aをbで割った**商(quotient)と余り(remainder)**を、それぞれタプル形式で同時に返す組み込み関数です。
返されるタプルは常に (商, 余り) の形式になります。
基本的な使い方
divmod(a, b) の形式で呼び出します。ここで、aは被除数(割られる数)、bは除数(割る数)です。
# 正の整数同士の割り算
print(divmod(10, 3)) # 出力: (3, 1) (10を3で割ると商は3、余りは1)
# 商と余りを個別の変数で受け取る
quotient, remainder = divmod(17, 5)
print(f"商: {quotient}, 余り: {remainder}") # 出力: 商: 3, 余り: 2
# 割り切れる場合
print(divmod(12, 4)) # 出力: (3, 0)
負の数の扱い
divmod()関数は、負の数を扱う際に少し注意が必要です。Pythonにおける剰余の定義は、結果の余りの符号が除数(b)の符号と同じになるように計算されます。商は、常に実数軸の負の無限大方向へ丸められます(床関数と同じ)。
# 被除数が負、除数が正
print(divmod(-10, 3)) # 出力: (-4, 2)
# -10 = 3 * (-4) + 2
# 被除数が正、除数が負
print(divmod(10, -3)) # 出力: (-4, -2)
# 10 = (-3) * (-4) + (-2)
# 被除数、除数ともに負
print(divmod(-10, -3)) # 出力: (3, -1)
# -10 = (-3) * 3 + (-1)
この負の数の挙動は、Pythonの//(床除算)演算子と%(剰余)演算子の組み合わせと同じ結果になります。
a = -10
b = 3
print(a // b) # 出力: -4 (商)
print(a % b) # 出力: 2 (余り)
浮動小数点数の扱い
divmod()は浮動小数点数も扱うことができます。この場合、商と余りも浮動小数点数で返されます。
print(divmod(10.5, 3)) # 出力: (3.0, 1.5)
print(divmod(7.0, 2.5)) # 出力: (2.0, 2.0) (7.0 = 2.5 * 2 + 2.0)
divmod()関数の重要性と活用事例
1. 効率的な計算
divmod()関数の最大の利点は、商と余りを一度の操作で同時に取得できることです。もしdivmod()を使わない場合、//演算子で商を計算し、%演算子で余りを計算する、という2つの独立した操作が必要になります。
# divmod()を使用
q, r = divmod(100, 7)
print(f"divmod() -> 商: {q}, 余り: {r}")
# 個別に計算
q_sep = 100 // 7
r_sep = 100 % 7
print(f"個別計算 -> 商: {q_sep}, 余り: {r_sep}")
内部的には、divmod()はこれらの計算をより効率的に(通常は単一のCPU命令で)実行できる場合があります。特にループ内で大量の割り算を行う場合など、パフォーマンスが重要となる場面で有効です。
2. 時間の単位変換
秒数を分と秒に、あるいは分を時間と分に変換するなど、時間関連の計算でよく使われます。
total_seconds = 200 # 200秒
minutes, seconds = divmod(total_seconds, 60)
print(f"{total_seconds}秒は {minutes}分 {seconds}秒 です。")
# 出力: 200秒は 3分 20秒 です。
# さらに時間への変換も組み合わせられる
total_minutes = 75
hours, remaining_minutes = divmod(total_minutes, 60)
print(f"{total_minutes}分は {hours}時間 {remaining_minutes}分 です。")
# 出力: 75分は 1時間 15分 です。
3. ページネーション(ページング処理)
ウェブサイトやアプリケーションで、大量のデータをページに分割して表示する際に、総アイテム数からページ数と最終ページの残りアイテム数を計算するのに役立ちます。
total_items = 123
items_per_page = 10
num_pages, last_page_items = divmod(total_items, items_per_page)
# 最後のページに残りがある場合はページ数を1増やす
if last_page_items > 0:
num_pages += 1
print(f"総アイテム数: {total_items}")
print(f"1ページあたりのアイテム数: {items_per_page}")
print(f"必要なページ数: {num_pages}")
print(f"最後のページのアイテム数: {last_page_items if last_page_items > 0 else items_per_page}")
# 出力: 必要なページ数: 13, 最後のページのアイテム数: 3
4. 座標変換やグリッド計算
2次元グリッド上での座標を1次元インデックスに変換したり、その逆を行ったりする際に、行と列の計算に利用できます。
# 1次元インデックスを2次元座標に変換 (5列のグリッド)
index = 17
num_cols = 5
row, col = divmod(index, num_cols)
print(f"インデックス {index} は ({row}行, {col}列) です。")
# 出力: インデックス 17 は (3行, 2列) です。
5. 数値の基数変換
10進数を2進数や16進数などに変換するアルゴリズムの内部で、繰り返し除算と剰余の計算を行う際に利用されます。
divmod()関数と関連する演算子
//(床除算)演算子
//演算子は、小数点以下を切り捨てて商のみを返します。これはdivmod()が返す商と常に同じ結果になります。
print(10 // 3) # 出力: 3
print(-10 // 3) # 出力: -4
%(剰余)演算子
%演算子は、割り算の余りのみを返します。これはdivmod()が返す余りと常に同じ結果になります。
print(10 % 3) # 出力: 1
print(-10 % 3) # 出力: 2
divmod(a, b) は基本的に (a // b, a % b) のショートカットであり、より効率的な実装を提供します。
まとめ
Pythonのdivmod()関数は、割り算の商と余りを効率的に同時に取得するための非常に便利な組み込み関数です。単に計算を簡潔にするだけでなく、内部的な最適化によりパフォーマンス面でも有利になる場合があります。時間変換、ページネーション、座標計算など、様々な実用的な場面でその真価を発揮します。
-
divmod(a, b)はaをbで割った商と余りをタプル(商, 余り)で返します。 -
負の数を含む場合、余りの符号は除数
bの符号と同じになります。 -
//演算子と%演算子を個別に使うよりも効率的である場合があります。 -
時間計算、ページング、グリッド座標変換など、多岐にわたる活用事例があります。
この関数を理解し適切に使いこなすことで、Pythonでの数値処理やアルゴリズムの実装がよりスムーズかつ効率的になるでしょう。
■プロンプトだけでオリジナルアプリを開発・公開してみた!!
■AI時代の第一歩!「AI駆動開発コース」はじめました!
テックジム東京本校で先行開始。
■テックジム東京本校
「武田塾」のプログラミング版といえば「テックジム」。
講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
より早く、より安く、しかも対面型のプログラミングスクールです。
<短期講習>5日で5万円の「Pythonミニキャンプ」開催中。
<月1開催>放送作家による映像ディレクター養成講座
<オンライン無料>ゼロから始めるPython爆速講座



