はじめに
Python では、辞書 (dictionary) はキーと値のペアを格納できる便利なデータ構造です。時には、辞書内の最大値のキーを見つける必要がある場合があります。このチャレンジでは、辞書を引数として受け取り、その辞書内の最大値のキーを返す関数を作成します。
This tutorial is from open-source community. Access the source code
💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください
Python では、辞書 (dictionary) はキーと値のペアを格納できる便利なデータ構造です。時には、辞書内の最大値のキーを見つける必要がある場合があります。このチャレンジでは、辞書を引数として受け取り、その辞書内の最大値のキーを返す関数を作成します。
まずは関数の核心部分を作成しましょう。段階的に構築していきます。最初に、key_of_max.py
という名前のファイルを作成します。LabEx の組み込みコードエディタを使用するか、nano
や vim
のようなターミナルベースのエディタを使用することができます。key_of_max.py
の中に、以下のコードを追加します。
def key_of_max(d):
"""
辞書 'd' 内の最大値に関連付けられたキーを返します。
複数のキーが最大値を共有する場合、そのいずれかが返されます。
"""
return max(d, key=d.get)
これを詳しく見ていきましょう。
def key_of_max(d):
: これは key_of_max
という名前の関数を定義しています。この関数は 1 つの引数 d
を受け取り、これは操作対象の辞書を表します。return max(d, key=d.get)
: これが関数の核心部分です。少しずつ分析してみましょう。
max(d,...)
: 組み込みの max()
関数は最大の要素を見つけます。デフォルトでは、max()
に辞書を渡すと、最大の キー(アルファベット順)を見つけます。しかし、私たちは最大の 値 に 関連付けられた キーを求めています。key=d.get
: これが重要な部分です。key
引数は max()
に要素の比較方法を指示します。d.get
は辞書のメソッドです。d.get(some_key)
を呼び出すと、some_key
に関連付けられた 値 が返されます。key=d.get
と設定することで、max()
に「辞書 d
の要素を 値 で比較し、キーではなく比較してください」と指示しています。その結果、max()
関数は最大値に対応する キー を返します。現在の関数には問題があります。入力の辞書 d
が空の場合、関数はクラッシュします。これを修正しましょう。key_of_max.py
を以下のように変更します。
def key_of_max(d):
"""
辞書 'd' 内の最大値に関連付けられたキーを返します。
複数のキーが最大値を共有する場合、そのいずれかが返されます。
"""
if not d: ## Check if the dictionary is empty
return None
return max(d, key=d.get)
追加された行は以下のような処理を行います。
if not d:
: Python では、空の辞書は「偽 (falsy)」と見なされます。この if
文は辞書 d
が空かどうかをチェックします。return None
: 辞書が空の場合、最大値は存在しないため、None
を返します。これは Python で値が存在しないことを示す標準的な方法です。これにより、max()
関数がエラーを発生させるのを防ぎます。これは堅牢なコードを書く上で重要なステップです。常にエッジケースを考慮しましょう!
では、関数が正しく動作することを確認するためにいくつかのテストを書きましょう。Python の unittest
モジュールを使用します。test_key_of_max.py
という名前の新しいファイルを作成し、以下のコードを追加します。
import unittest
from key_of_max import key_of_max ## Import our function
class TestKeyOfMax(unittest.TestCase):
def test_basic_case(self):
self.assertEqual(key_of_max({'a': 4, 'b': 0, 'c': 13}), 'c')
def test_another_case(self):
self.assertEqual(key_of_max({'apple': 10, 'banana': 5, 'orange': 10}), 'apple')
if __name__ == '__main__':
unittest.main()
説明:
import unittest
: テストフレームワークをインポートします。from key_of_max import key_of_max
: テスト対象の関数をインポートします。class TestKeyOfMax(unittest.TestCase):
: テストクラス を定義します。テストクラスは関連するテストをまとめます。def test_basic_case(self):
: テストメソッド を定義します。各テストメソッドは関数の特定の側面をチェックします。テストメソッド名は必ず test_
で始める必要があります。self.assertEqual(...)
: これは アサーション です。2 つの値が等しいかどうかをチェックします。等しくない場合、テストは失敗します。この場合、key_of_max({'a': 4, 'b': 0, 'c': 13})
が 'c'
を返すかどうかをチェックしています。def test_another_case(self):
: 最大値のキーが一意でない場合を検証するための別のテストケースを追加しました。if __name__ == '__main__': unittest.main()
: この標準的な Python の慣用句は、スクリプトを直接実行するときにテストを実行します(例:python3 test_key_of_max.py
)。ターミナルからテストを実行します:python3 test_key_of_max.py
。2 つのテストが合格したことを示す出力が表示されるはずです。
python3 test_key_of_max.py
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
空の辞書のケースに特化したテストを追加しましょう。test_key_of_max.py
の TestKeyOfMax
クラスに以下のメソッドを追加します。
def test_empty_dictionary(self):
self.assertIsNone(key_of_max({}))
self.assertIsNone(...)
: このアサーションは、値が具体的に None
であるかどうかをチェックします。これは重要です。なぜなら、self.assertEqual(..., None)
は None
に 評価される ものに対して合格する可能性がありますが、実際に None
ではない場合もあります。assertIsNone
はより厳密です。再度テストを実行します(python3 test_key_of_max.py
)。3 つのテスト(2 つの基本テストと空の辞書のテスト)がすべて合格するはずです。
python3 test_key_of_max.py
----------------------------------------------------------------------
Ran 3 tests in 0.000s
OK
最後のテストとして、辞書内のすべての値が負の場合を扱いましょう。TestKeyOfMax
に以下のメソッドを追加します。
def test_all_negative_values(self):
self.assertEqual(key_of_max({'x': -5, 'y': -2, 'z': -10}), 'y')
このテストは、関数が「最も負の値が小さい」(この場合の最大値)を正しく識別し、それに関連付けられたキーを返すことを保証します。
最後に一度テストを実行しましょう(python3 test_key_of_max.py
)。4 つのテストすべてが合格するはずです。これにより、関数が正しく動作していることを高い確信を持って確認できます。
完成した test_key_of_max.py
は以下のようになるはずです。
import unittest
from key_of_max import key_of_max
class TestKeyOfMax(unittest.TestCase):
def test_basic_case(self):
self.assertEqual(key_of_max({'a': 4, 'b': 0, 'c': 13}), 'c')
def test_another_case(self):
self.assertEqual(key_of_max({'apple': 10, 'banana': 5, 'orange': 10}), 'apple')
def test_empty_dictionary(self):
self.assertIsNone(key_of_max({}))
def test_all_negative_values(self):
self.assertEqual(key_of_max({'x': -5, 'y': -2, 'z': -10}), 'y')
if __name__ == '__main__':
unittest.main()
再度テストを実行します(python3 test_key_of_max.py
)。4 つのテストすべてが合格するはずです。これにより、関数が正しく動作していることを高い確信を持って確認できます。
python3 test_key_of_max.py
----------------------------------------------------------------------
Ran 4 tests in 0.000s
OK
この実験では、辞書内の最大値に関連付けられたキーを見つける Python 関数 key_of_max
を作成しました。max()
関数をカスタムの key
引数とともに使用する方法を学び、空の辞書という重要なエッジケースを処理しました。また、unittest
モジュールを使用して基本的なケース、空の辞書、すべての値が負の辞書などを網羅した包括的な単体テストを作成しました。このような機能コードと包括的なテストの組み合わせは、良好なソフトウェア開発の実践を示しています。