
本文旨在提供一个高效的 Python 函数,用于查找数组中出现频率最高的数字。如果多个数字具有相同的最高频率,该函数将返回其中最大的数字。我们将探讨使用 defaultdict 的优化实现,并提供不使用 defaultdict 的替代方案,同时对比不同实现的性能差异。
使用 defaultdict 实现
collections.defaultdict 是 Python 中一个非常有用的数据结构,它可以简化计数操作。当尝试访问 defaultdict 中不存在的键时,它会自动使用指定的默认值创建该键。这避免了手动检查键是否存在的需求,从而使代码更简洁易读。
以下是使用 defaultdict 查找数组中频率最高的数字的函数:
from collections import defaultdict
def highest_rank(arr):
count = defaultdict(int)
highest_rank = 0
highest_rank_cnt = 0
for num in arr:
cnt = count[num] + 1
count[num] = cnt
if cnt > highest_rank_cnt or (cnt == highest_rank_cnt and num > highest_rank):
highest_rank = num
highest_rank_cnt = cnt
return highest_rank代码解释:
立即学习“Python免费学习笔记(深入)”;
- from collections import defaultdict: 导入 defaultdict 类。
- count = defaultdict(int): 创建一个 defaultdict 对象,默认值为整数 0。
- highest_rank = 0: 初始化 highest_rank 变量,用于存储当前频率最高的数字。
- highest_rank_cnt = 0: 初始化 highest_rank_cnt 变量,用于存储当前最高频率。
- for num in arr:: 遍历输入数组 arr。
- cnt = count[num] + 1: 增加数字 num 的计数。如果 num 之前不在 count 中,defaultdict 会自动创建 num 键并将其值初始化为 0,然后再加 1。
- count[num] = cnt: 更新数字 num 的计数。
- if cnt > highest_rank_cnt or (cnt == highest_rank_cnt and num > highest_rank):: 检查当前数字 num 的频率是否高于当前最高频率,或者频率相同但 num 大于当前的 highest_rank。如果是,则更新 highest_rank 和 highest_rank_cnt。
- return highest_rank: 返回频率最高的数字。
示例:
arr = [9, 48, 1, 8, 44, 45, 32, 48] result = highest_rank(arr) print(result) # 输出 48
不使用 defaultdict 的实现
如果不希望使用 defaultdict,可以使用标准的 dict 以及 if num not in count 检查来实现相同的功能。
def highest_rank_no_defaultdict(arr):
count = {}
highest_rank = 0
highest_rank_cnt = 0
for num in arr:
if num not in count:
cnt = 1
else:
cnt = count[num] + 1
count[num] = cnt
if cnt > highest_rank_cnt or (cnt == highest_rank_cnt and num > highest_rank):
highest_rank = num
highest_rank_cnt = cnt
return highest_rank这段代码与使用 defaultdict 的版本的功能相同,但它显式地检查数字是否已存在于 count 字典中。
性能比较
使用 defaultdict 的实现通常比不使用的实现略快,因为它可以避免每次访问计数器时进行额外的键检查。以下是一个简单的性能比较示例:
import timeit
import random
def highest_rank_defaultdict(arr):
from collections import defaultdict
count = defaultdict(int)
highest_rank = 0
highest_rank_cnt = 0
for num in arr:
cnt = count[num] + 1
count[num] = cnt
if cnt > highest_rank_cnt or (cnt == highest_rank_cnt and num > highest_rank):
highest_rank = num
highest_rank_cnt = cnt
return highest_rank
def highest_rank_no_defaultdict(arr):
count = {}
highest_rank = 0
highest_rank_cnt = 0
for num in arr:
if num not in count:
cnt = 1
else:
cnt = count[num] + 1
count[num] = cnt
if cnt > highest_rank_cnt or (cnt == highest_rank_cnt and num > highest_rank):
highest_rank = num
highest_rank_cnt = cnt
return highest_rank
# 创建一个包含 10000 个随机整数的数组
arr = [random.randint(0, 1000) for _ in range(10000)]
# 测量使用 defaultdict 的函数的执行时间
time_defaultdict = timeit.timeit(lambda: highest_rank_defaultdict(arr), number=1000)
# 测量不使用 defaultdict 的函数的执行时间
time_no_defaultdict = timeit.timeit(lambda: highest_rank_no_defaultdict(arr), number=1000)
print(f"使用 defaultdict 的执行时间: {time_defaultdict:.4f} 秒")
print(f"不使用 defaultdict 的执行时间: {time_no_defaultdict:.4f} 秒")在大多数情况下,使用 defaultdict 的版本会略快,但差异可能很小,具体取决于输入数据的分布和大小。
总结
本文介绍了如何使用 Python 查找数组中频率最高的数字。我们探讨了使用 defaultdict 和不使用 defaultdict 的两种实现方式,并比较了它们的性能。使用 defaultdict 通常是更简洁和高效的选择,但在某些情况下,不使用 defaultdict 的实现可能更适合。在选择实现方式时,请考虑您的具体需求和性能要求。










