简介
在 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的函数。它接受一个参数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 中,空字典被视为“假值”。这个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(...)**:这是一个 _断言_。它检查两个值是否相等。如果它们不相等,测试就会失败。在这种情况下,我们检查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。你应该会看到输出,表明这两个测试都通过了。
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)。现在,所有三个测试(两个基础测试和空字典测试)都应该通过。
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)。所有四个测试都应该通过。这让我们有足够的信心认为我们的函数能正常工作。
你完整的 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)。所有四个测试都应该通过。这让我们有足够的信心认为我们的函数能正常工作。
python3 test_key_of_max.py
----------------------------------------------------------------------
Ran 4 tests in 0.000s
OK
总结
在这个实验中,你编写了一个 Python 函数 key_of_max,用于找出字典中与最大值关联的键。你学习了如何使用带有自定义 key 参数的 max() 函数,还处理了空字典这一重要的边界情况。你还使用 unittest 模块编写了全面的单元测试,涵盖了基础情况、空字典以及所有值均为负数的字典。这种将功能代码与全面测试相结合的方式体现了良好的软件开发实践。