Python 3.14のheapqで最大値から取り出す方法|heappop_maxの使い方

入力listをheapify_maxで最大ヒープに変換し、12を追加して最大値から順に取り出す流れの図解

Python 3.14では、標準ライブラリのheapqに最大ヒープ用の公開APIが追加されました。大きい値を順に取り出す処理を、負数化せずheapify_max()やheappop_max()で書けます。

対象: Python 3.14以上。確認日は2026年10月16日です。ITtrip側のWindows上のCPython 3.14.8で、本文の基本例と複合操作の結果を確認しています。

目次

まずは最短例:最大値から順に取り出す

既存のlistをheapify_max()で最大ヒープに変換し、heappush_max()で値を追加します。その後、空になるまでheappop_max()を呼べば、大きい値から順に取り出せます。

import heapq

h = [4, 9, 1, 7]

heapq.heapify_max(h)
heapq.heappush_max(h, 12)

result = []
while h:
    result.append(heapq.heappop_max(h))

print(result)

想定出力です。

[12, 9, 7, 4, 1]

heapify_max(h)は渡したhをその場で変換します。最大値はh[0]ですが、list全体が降順になる保証はありません。

Python 3.14で追加された5つの公開API

関数役割注意点
heapq.heapify_max(x)既存のlistを最大ヒープへその場で変換戻り値ではなく、元のlistが変わる
heapq.heappush_max(heap, item)最大ヒープへ値を追加追加後もheap[0]が最大値
heapq.heappop_max(heap)最大値を削除して返す空のヒープではIndexError
heapq.heappushpop_max(heap, item)値を追加してから最大値を返す追加した値自身が返る場合がある
heapq.heapreplace_max(heap, item)現在の最大値を返し、新しい値で置き換える空のヒープではIndexError

5つともPython 3.14で追加された公開APIです。通常のheapify()、heappush()、heappop()と_max関数を、同じヒープへ混在させないでください。

入力list、最大ヒープ化、値の追加、最大値の取り出しを矢印でつないだ日本語の処理図
最大ヒープではheap[0]が最大値になるが、内部list全体が降順になるとは限らない。 · 図を拡大

負数化する従来例とPython 3.14の対応

Python 3.13以下では公開された最大ヒープAPIがないため、数値を負数にして最小ヒープへ入れ、取り出すときに符号を戻す方法があります。

import heapq

values = [4, 9, 1, 7]
h = [-value for value in values]

heapq.heapify(h)
heapq.heappush(h, -12)

result = []
while h:
    result.append(-heapq.heappop(h))

print(result)
[12, 9, 7, 4, 1]

Python 3.14以上では、同じ処理を冒頭のheapify_max()、heappush_max()、heappop_max()で直接書けます。対応関係は次のとおりです。

操作Python 3.14の最大ヒープ負数化する方法
既存データをヒープ化heapq.heapify_max(h)h = [-x for x in values]の後にheapq.heapify(h)
値を追加heapq.heappush_max(h, x)heapq.heappush(h, -x)
最大値を取り出すheapq.heappop_max(h)-heapq.heappop(h)
最大値を見るだけh[0]-h[0]

負数化は数値向けの互換策で、文字列などにはそのまま使えません。Python 3.13以下でも、アンダースコア付きの内部関数を公開APIの代替として勧めることはできません。

heapreplace_maxとheappushpop_maxの違い

名前が似ていますが、処理の順序が違います。まずheapreplace_max()は、現在の最大値を先に取り出してから新しい値を追加します。次の[9, 4]は、2要素の最大ヒープとして有効です。

import heapq

h = [9, 4]

removed = heapq.heapreplace_max(h, 12)

print(removed)
print(h)
9
[12, 4]

現在の最大値9が返り、追加した12はヒープに残ります。

一方、heappushpop_max()は新しい値を追加してから、その時点の最大値を返します。

import heapq

h = [9, 4]

returned = heapq.heappushpop_max(h, 12)

print(returned)
print(h)
12
[9, 4]

12自身が最大なので、そのまま返り、元の[9, 4]が残ります。既存の最大値を先に除くのがheapreplace_max()、追加後の最大値を返すのがheappushpop_max()です。

実行版と機能の有無を確認する

まず、実際に使われているPythonの版を確認します。

python --version

今回の確認環境では次の表示です。

Python 3.14.8

プログラム内ではsys.version_infoとhasattr()を使うと、必要な関数が公開されているか確認できます。

import heapq
import sys

names = (
    "heapify_max",
    "heappush_max",
    "heappop_max",
    "heappushpop_max",
    "heapreplace_max",
)

print(sys.version_info[:3])
print({name: hasattr(heapq, name) for name in names})
(3, 14, 8)
{'heapify_max': True, 'heappush_max': True, 'heappop_max': True, 'heappushpop_max': True, 'heapreplace_max': True}

ITtrip側で確認したCPython 3.13.7には、これらの公開_max関数はありませんでした。複数版へ対応するコードでは、少なくともhasattr(heapq, "heapify_max")を分岐条件にし、3.13以下では数値の負数化など、公開APIだけで構成した互換処理を用意します。

よくある間違い

  • heapify_max()後のlistを降順済みだと思う: 保証されるのは最大値がheap[0]にあることと、最大ヒープの規則を満たすことです。全要素の表示順には依存しません。
  • 最小ヒープ用と最大ヒープ用の関数を混ぜる: 同じhには、通常関数か_max関数のどちらか一方だけを使います。
  • 空のヒープから取り出す: heappop_max([])はIndexErrorになります。全件を処理するならwhile h:で空かどうかを確認できます。
  • 内部APIへ依存する: アンダースコアで始まる名前は公開APIではありません。3.14未満への対応は、公開関数を使った負数化などで行います。

max・nlargest・sortedも検討する

データを更新しながら最大値を何度も取り出すのでなければ、別の標準機能の方が意図を直接表せる場合があります。

目的候補
最大値を1個だけ求めるmax(values)
固定データから上位n個を得るheapq.nlargest(n, values)
全件を降順のlistにするsorted(values, reverse=True)
追加と最大値の取り出しを繰り返すheapqの最大ヒープAPI

用途とデータの扱い方で選びます。最大ヒープが常に最速である、という前提は置かず、必要な操作が「更新しながら最大値を繰り返し取り出すこと」かどうかで判断すると分かりやすくなります。

FAQ

Python 3.13でheappush_maxは使えますか?

公開APIとしては使えません。Python 3.14以上へ更新するか、数値なら負数化して通常のheappush()とheappop()を使います。

heapify_maxの戻り値を変数へ代入できますか?

heapify_max()はlistをその場で変換するため、変換後も元の変数を使います。h = heapq.heapify_max(h)とは書かず、heapq.heapify_max(h)と単独で呼び出します。

最大値を削除せず確認する方法は?

ヒープが空でなければh[0]で確認できます。削除も行う場合はheappop_max(h)を使います。

公式出典

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次