Python面试题:如何快速调换字典中的key和value
今天我们来聊一聊一个非常基础但却能考察你对 Python 字典操作熟练程度的面试题——如何快速调换字典中的 key 和 value。也许你会觉得这个问题简单,但是面试官有时候就喜欢拿这些看似简单但能考察你基础功底的问题来试探你。
首先呢,我们从字典的基本操作说起。Python 中的字典是一个非常常见的数据结构,它存储的是键值对。字典中的每个键(key)都是唯一的,可以通过 key 获取对应的 value。我们平时在编程中,经常需要操作字典,比如获取、修改、删除数据。但有时候,我们需要调换字典中的 key 和 value,也就是让原来的 key 成为新的 value,原来的 value 成为新的 key。
问题分析
假设我们有一个字典,它的 key 和 value 是一一对应的:
original_dict = {'a': 1, 'b': 2, 'c': 3}
现在我们想要调换字典中的 key 和 value,也就是说,期望的结果是:
{'1': 'a', '2': 'b', '3': 'c'}
乍一看,这个问题似乎简单得不能再简单了——只是调换一下顺序而已。但其实,这背后有几个细节需要注意。
方案一:字典推导式(最简洁的做法)
Python 提供了一种非常简洁的方式来调换字典中的 key 和 value,那就是通过字典推导式。字典推导式是 Python 中用于创建字典的简洁语法。我们可以用它来快速完成这一任务。
original_dict = {'a': 1, 'b': 2, 'c': 3}
reversed_dict = {v: k for k, v in original_dict.items()}
print(reversed_dict)
这段代码的意思是:遍历 original_dict 中的每一对 key-value,然后交换它们的位置,生成一个新的字典。执行结果是:
{1: 'a', 2: 'b', 3: 'c'}
是不是很简单?不过这里有个需要注意的地方:字典中的 key 必须是可哈希的。这就意味着字典中的 value 如果是可变数据类型(比如列表、字典等),那么就无法作为新的 key。
方案二:使用 map 函数(相对不常见)
除了字典推导式,还有另一种比较“炫酷”的做法,那就是使用 map() 函数来实现调换 key 和 value。不过,这种方法相对来说不太常见,通常情况下我们还是会选择字典推导式。不过作为一种可选方案,了解一下也是可以的。
original_dict = {'a': 1, 'b': 2, 'c': 3}
reversed_dict = dict(map(lambda item: (item[1], item[0]), original_dict.items()))
print(reversed_dict)
这里我们用 map() 函数将原字典中的 key-value 对转换成 (value, key),然后再通过 dict() 将结果转换回字典。
输出结果:
{1: 'a', 2: 'b', 3: 'c'}
这也是一种有效的方式,但是在 Python 中,推导式一般会被认为更清晰和简洁。
方案三:遍历字典手动构建(性能较差,不推荐)
如果你想要一个更“手动”的方法,也可以通过普通的 for 循环来实现。这种方式实现起来比较原始,代码不如前两种方法简洁,性能也相对较差,但我还是给大家举个例子,免得大家在面试中碰到时一头雾水。
original_dict = {'a': 1, 'b': 2, 'c': 3}
reversed_dict = {}
for key, value in original_dict.items():
reversed_dict[value] = key
print(reversed_dict)
结果依然是:
{1: 'a', 2: 'b', 3: 'c'}
这种方式比较直接,但是因为每次要手动修改 reversed_dict,所以效率和可读性都不如推导式。
问题的深入分析:处理冲突
在现实的工作中,字典中的 key 和 value 不一定是唯一的。这时候,调换 key 和 value 的操作就变得复杂了。
假设我们有一个字典,其中存在重复的 value:
original_dict = {'a': 1, 'b': 1, 'c': 2}
当我们调换 key 和 value 后,新的字典就会出现冲突:
{1: 'b', 2: 'c'}
在这种情况下,字典的 key 不能重复,因此只会保留一个 key 对应多个 value。那么如何解决这个问题呢?
一种常见的做法是将冲突的 value 转换成列表,存储多个 key:
original_dict = {'a': 1, 'b': 1, 'c': 2}
reversed_dict = {}
for key, value in original_dict.items():
if value not in reversed_dict:
reversed_dict[value] = [key]
else:
reversed_dict[value].append(key)
print(reversed_dict)
输出结果:
{1: ['a', 'b'], 2: ['c']}
这样我们就能处理 value 重复的情况,将重复的 key 保存在一个列表中。
Python3.7+ 字典的插入顺序
Python3.7 及之后的版本中,字典保持了插入顺序,也就是说,字典会按插入的顺序来存储 key-value 对。这个特性对我们调换 key 和 value 操作的结果没有直接影响,但是它保证了调换顺序后,新的字典会按照原字典的顺序进行排列。
所以,如果你在 Python3.7+ 中运行上面的代码,调换后的字典顺序会保持与原字典相同。
总结
在 Python 中,调换字典中的 key 和 value 并不复杂。最常用且高效的方式是使用字典推导式,它不仅代码简洁,而且能够应对大多数常见场景。当然,如果你有特殊需求,比如处理 value 重复的情况,也可以通过稍微复杂的逻辑来解决。
对编程、职场感兴趣的同学,大家可以联系我微信:golang404,拉你进入“程序员交流群”。
虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》。