Python 中查找最大值对应的键

PythonPythonBeginner
立即练习

This tutorial is from open-source community. Access the source code

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

在 Python 中,字典(dictionary)是一种实用的数据结构,它允许你存储键值对。有时,你可能需要找出字典中最大值所对应的键。在这个挑战中,你需要编写一个函数,该函数接受一个字典作为参数,并返回该字典中最大值所对应的键。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL python(("Python")) -.-> python/BasicConceptsGroup(["Basic Concepts"]) python(("Python")) -.-> python/ControlFlowGroup(["Control Flow"]) python(("Python")) -.-> python/DataStructuresGroup(["Data Structures"]) python(("Python")) -.-> python/FunctionsGroup(["Functions"]) python(("Python")) -.-> python/ModulesandPackagesGroup(["Modules and Packages"]) python/BasicConceptsGroup -.-> python/comments("Comments") python/ControlFlowGroup -.-> python/conditional_statements("Conditional Statements") python/DataStructuresGroup -.-> python/tuples("Tuples") python/DataStructuresGroup -.-> python/dictionaries("Dictionaries") python/FunctionsGroup -.-> python/function_definition("Function Definition") python/FunctionsGroup -.-> python/build_in_functions("Build-in Functions") python/ModulesandPackagesGroup -.-> python/importing_modules("Importing Modules") python/ModulesandPackagesGroup -.-> python/standard_libraries("Common Standard Libraries") subgraph Lab Skills python/comments -.-> lab-13677{{"Python 中查找最大值对应的键"}} python/conditional_statements -.-> lab-13677{{"Python 中查找最大值对应的键"}} python/tuples -.-> lab-13677{{"Python 中查找最大值对应的键"}} python/dictionaries -.-> lab-13677{{"Python 中查找最大值对应的键"}} python/function_definition -.-> lab-13677{{"Python 中查找最大值对应的键"}} python/build_in_functions -.-> lab-13677{{"Python 中查找最大值对应的键"}} python/importing_modules -.-> lab-13677{{"Python 中查找最大值对应的键"}} python/standard_libraries -.-> lab-13677{{"Python 中查找最大值对应的键"}} end

创建基本函数

让我们从创建函数的核心部分开始。我们将逐步构建它。首先,创建一个名为 key_of_max.py 的文件。你可以使用内置的 LabEx 代码编辑器,或者像 nanovim 这样的基于终端的编辑器。在 key_of_max.py 中,添加以下代码:

代码编辑器中的 key_of_max 函数
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()

解释:

  1. import unittest:导入测试框架。
  2. from key_of_max import key_of_max:导入我们要测试的函数。
  3. class TestKeyOfMax(unittest.TestCase)::定义一个 测试类。测试类将相关的测试组合在一起。
  4. def test_basic_case(self)::定义一个 测试方法。每个测试方法检查我们函数的一个特定方面。测试方法的名称 必须test_ 开头。
  5. self.assertEqual(...):这是一个 断言。它检查两个值是否相等。如果它们不相等,测试就会失败。在这种情况下,我们检查 key_of_max({'a': 4, 'b': 0, 'c': 13}) 是否返回 'c',它应该返回这个值。
  6. def test_another_case(self)::添加另一个测试用例,以验证最大值对应的键可能不唯一的情况。
  7. 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.pyTestKeyOfMax 类中添加以下方法:

    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 模块编写了全面的单元测试,涵盖了基础情况、空字典以及所有值均为负数的字典。这种将功能代码与全面测试相结合的方式体现了良好的软件开发实践。