You need to enable JavaScript to run this app. 为什么应用set()查找列表频次极值元素时结果存在差异
优惠活动
大模型
产品
解决方案
定价
更多

为什么应用set()查找列表频次极值元素时结果存在差异

带key=lst.count的max/min操作 加/不加set()结果差异的原理解析

核心运行规则

  • max/min配合key参数的并列处理逻辑:遍历可迭代对象时,仅当当前元素的key值严格大于(max场景)/严格小于(min场景)已记录的极值时,才更新当前的极值对象;key值与极值相等时,直接跳过不更新。这意味着当多个元素的key值完全持平时,最终返回的结果一定是整个迭代过程中第一个被碰到的、持有该极值key值的元素。
  • 提前计算所有元素对应的lst.count()值:
    • 字符A:在原列表中出现1次
    • 字符B:在原列表中出现3次
    • 字符C:在原列表中出现3次
    • 字符E:在原列表中出现1次
      即所有元素的最高key值为3(B、C并列),最低key值为1(A、E并列),存在两组完全对等的并列场景。

直接传入原列表的执行结果逻辑

直接将原列表lst作为可迭代对象传入时,迭代顺序完全固定为列表的物理存储顺序:A → B → B → B → C → C → C → E

  • 执行max(lst, key=lst.count)时,第一个拿到最高key值3的元素是索引1位置的B,后续遍历到的所有C元素虽然key值同样为3,但因不满足“严格大于当前极值”的条件,不会触发更新,最终返回B。
  • 执行min(lst, key=lst.count)时,第一个拿到最低key值1的元素是索引0位置的A,后续遍历到的E元素虽然key值同样为1,但因不满足“严格小于当前极值”的条件,不会触发更新,最终返回A。

传入set(lst)的执行结果逻辑

这里的核心认知偏差,是多数人默认set(lst)的迭代顺序是“原列表去重后的自然顺序”(即A→B→C→E),但实际上:

  • set是典型的无序容器,Python3.7之前的版本完全不保证set的迭代顺序,顺序由元素哈希值、内存布局随机决定;3.7之后的版本虽然将“set保留元素第一次插入的顺序”纳入语言规范,但这个插入顺序和我们预想的“原列表去重顺序”没有必然关联,更不会和自然字母顺序匹配。
  • 从给出的运行结果可以反推,在当前运行环境下,set(lst)的实际迭代顺序为C → B → E → A,完全贴合得到的返回结果:
    1. 执行max(set(lst), key=lst.count)时,第一个拿到最高key值3的元素是C,后续遍历到的B元素key值同样为3,因不满足严格大于的条件不触发更新,最终返回C。
    2. 执行min(set(lst), key=lst.count)时,遍历过程中第一个拿到最低key值1的元素是E,后续遍历到的A元素key值同样为1,因不满足严格小于的条件不触发更新,最终返回E。
  • 这个结果不具备普适性:只要换一个Python版本、甚至重启同一个Python解释器,set(lst)的迭代顺序就可能发生变化,对应的max/min返回值也会同步变化——毕竟在key值并列的前提下,谁先被迭代到,谁就是最终的返回结果。

内容的提问来源于stack exchange,提问作者Daniel Hao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.02 20:24:03