Python中使用max()、set()查找列表最高频元素的代码原理是什么?
首先我们再把你提到的代码贴出来方便对照:
def most_frequent(List): return max(set(List), key = List.count)
1. 先搞懂max()的两种用法
你之前接触的是max()的第一种传参形式:传入多个独立的数值/字符串参数,直接比较参数本身的大小返回最大值,比如max(4,2,6,3,2)返回6。
这里用到的是第二种传参形式:第一个参数传入可迭代对象(列表、集合、元组都属于可迭代对象),max()会遍历这个可迭代对象的所有元素,找到其中的最大值。
2. key参数的作用
key是max()的可选参数,接收一个函数作为值。指定key后,max()不会直接比较可迭代对象的元素本身大小,而是把每个元素传入key对应的函数,用函数的返回值作为比较依据,最终返回「返回值最大」对应的原始元素。
举个简单的例子就很容易理解:
# 比较字符串长度,返回最长的字符串 print(max(["苹果", "香蕉", "哈密瓜", "西瓜"], key=len)) # 输出结果:哈密瓜
这里key=len就是把每个字符串传给len()计算长度,再比较长度的大小,返回长度最大的字符串。
回到你提供的代码,key = List.count,List.count是Python列表自带的计数方法,作用是统计指定元素在列表中出现的次数。也就是说这里max()会把每个元素传给List.count算出出现次数,比较后返回出现次数最多的元素。
3. 转set的作用
set(List)的作用是对原列表去重,只保留所有唯一的元素。
如果不转set,直接把原列表传给max也能得到正确结果,但会产生大量冗余计算:比如原列表里同一个元素出现了100次,max()遍历到这100次的时候,每次都要重新算一遍这个元素的出现次数,完全是浪费性能。转成set后每个唯一元素只需要计算1次出现次数,执行效率高得多,尤其是在列表长度大、重复元素多的时候差异非常明显。
完整运行流程示例
我们用实际的列表走一遍完整流程,你就能完全理解:
假设输入列表是List = [2,5,2,8,2,5,6,2,1]
- 首先执行
set(List)得到去重后的唯一元素集合:{1,2,5,6,8} - 对集合里的每个元素执行
List.count计算出现次数:- 1出现1次
- 2出现4次
- 5出现2次
- 6出现1次
- 8出现1次
max()比较所有次数,最大的次数是4,对应的原始元素是2,最终返回2,就是列表里出现频率最高的元素。
小补充:如果列表里有多个元素出现次数同为最高值,因为集合的遍历顺序不固定,最终只会返回其中一个,如果你需要返回所有最高频率的元素,需要修改逻辑额外处理。
内容的提问来源于stack exchange,提问作者Preston_Jarvis

