cmp関数とは?

cmp関数は、Python 2で使用されていた2つのオブジェクトを比較するための組み込み関数です。cmpを使うと、2つのオブジェクトがどちらが大きいか、等しいかを判定し、以下のような結果を返します。

  • 左のオブジェクトが小さい場合は-1
  • 左のオブジェクトと右のオブジェクトが等しい場合は0
  • 左のオブジェクトが大きい場合は1
# `Python` 2での例
print(cmp(3, 5))  # 出力: -1 (3 < 5)
print(cmp(5, 5))  # 出力: 0  (5 == 5)
print(cmp(7, 5))  # 出力: 1  (7 > 5)

このように、cmp関数は整数や文字列、リストなどのオブジェクトを比較するために使われていました。しかし、Python 3ではcmp関数は廃止されているため、直接使用することはできません。

Python 3での比較方法

Python 3では、cmp関数の代わりに比較演算子(<>==など)を使ってオブジェクト同士を比較することが一般的です。

例 - 比較演算子を使ったオブジェクトの比較

# `Python` 3での比較
x = 3
y = 5
# xがyより小さいか?
print(x < y)  # 出力: True
# xとyが等しいか?
print(x == y)  # 出力: False
# xがyより大きいか?
print(x > y)  # 出力: False

このように、Python 3では<>==などの演算子を使って直接オブジェクトの比較を行います。

文字列やリストの比較

Pythonでは、文字列やリストも比較可能で、辞書順や要素の順序に基づいて比較が行われます。

# 文字列の比較(辞書順)
print("apple" < "banana")  # 出力: True
# リストの比較(各要素の比較)
print([1, 2, 3] > [1, 2])  # 出力: True

このように、Python 3では多くのデータ型がネイティブに比較可能です。

Python 3でのcmpの代替 - functools.cmp_to_key

Python 3でcmp関数のような機能を使いたい場合、functoolsモジュールに含まれるcmp_to_key関数を使うことができます。この関数は、Python 2スタイルの比較関数をPython 3のソート機能に適用するためのラッパー関数を提供します。 cmp_to_keyを使うと、cmpスタイルの関数をキー関数に変換して、Python 3のsortedlist.sortに利用できます。

functools.cmp_to_keyの使い方

以下の例では、カスタムの比較関数をcmp_to_keyで変換し、ソートに利用する方法を示します。

from functools import cmp_to_key
# カスタムのcmpスタイル関数
def custom_cmp(x, y):
    if x < y:
        return -1
    elif x > y:
        return 1
    else:
        return 0
# cmp_to_keyでキー関数に変換
sorted_list = sorted([3, 1, 4, 1, 5, 9], key=cmp_to_key(custom_cmp))
print(sorted_list)  # 出力: [1, 1, 3, 4, 5, 9]

このように、cmp_to_keyを使って、cmp関数の代替としてカスタムの比較を定義し、sorted関数で利用できます。

Python 3でのcmp関数が廃止された理由

Python 3では、コードのシンプルさや読みやすさを重視して、cmp関数を廃止しました。比較演算子(<>==など)を使うことで、より直感的でわかりやすい比較が可能です。さらに、Python 3ではキー関数を使うソートが推奨されており、キーを用いた比較はより効率的で柔軟です。 たとえば、sorted関数やlist.sort関数では、比較関数ではなく、ソート基準となるキー関数を指定するのが一般的です。

例 - キー関数を使ったソート

キー関数を使えば、カスタムのソートも簡単に実現できます。以下の例では、リストの各要素の絶対値を基準にソートしています。

# キー関数を使って絶対値でソート
numbers = [-4, 2, -7, 1, 0, 9, -3]
sorted_numbers = sorted(numbers, key=abs)
print(sorted_numbers)  # 出力: [0, 1, 2, -3, -4, -7, 9]

このように、key引数にabs関数を渡すことで、リストの要素を絶対値でソートしています。

cmp関数をPython 3で再実装する方法

Python 3でcmp関数のような機能を再実装する場合、次のように比較演算子を組み合わせて同じ動作を実現できます。

def cmp(a, b):
    return (a > b) - (a < b)
# テスト例
print(cmp(3, 5))  # 出力: -1
print(cmp(5, 5))  # 出力: 0
print(cmp(7, 5))  # 出力: 1

この例では、(a > b)Trueの場合は1、(a < b)Trueの場合は-1、それ以外は0を返すことでcmpと同じ結果を得ています。

まとめ

cmp関数はPython 2で提供されていた比較関数で、2つのオブジェクトを比較してその大小関係を判定するものでした。しかし、Python 3では比較演算子やキー関数の使用が推奨され、cmp関数は廃止されました。Python 3でcmpに相当する動作を実現するには、functools.cmp_to_keyを使ってカスタム ソートを行うか、比較演算子を利用することで柔軟に対応できます。 cmpスタイルの比較が必要な場合でも、Python 3のモダンな手法を活用して、コードの読みやすさや効率を向上させましょう。