defaultdict应传入可调用对象而非调用结果,如defaultdict(list)正确,defaultdict(list())错误;most_common(n)返回普通list,非Counter子集;namedtuple不可变,修改需用_replace();deque设maxlen会静默丢弃旧元素。

defaultdict 初始化时传入可调用对象,不是调用结果
很多人写 defaultdict(list) 没问题,但换成 defaultdict(list()) 就报错或行为异常——后者会立即执行 list(),返回空列表对象,导致所有键共享同一个 list 实例。
正确做法是传入类型名或 lambda:
-
defaultdict(list)—— 安全,每次缺省时调用list() -
defaultdict(lambda: [])—— 灵活,适合带参数的构造(如lambda: [0] * 3) -
defaultdict(int)等同于defaultdict(lambda: 0),但更简洁
注意:传入函数必须无参,否则运行时报 TypeError: ——因为 defaultdict 内部会自动传入缺失的 key 给工厂函数(仅当工厂函数支持该签名时才生效;多数内置类型如 list、int 忽略参数,但自定义函数需显式接收并忽略)。
Counter 的 most_common(n) 返回 list,不是 Counter 子集
most_common(3) 返回的是 [(key, count), ...] 形式的普通 list,不保留 Counter 类型,也不能直接继续链式调用 update() 或 elements()。
立即学习“Python免费学习笔记(深入)”;
常见误用场景:
- 想取 top-3 后再过滤:得先转回
Counter(dict(c.most_common(3))) - 想按频次排序但保留计数器行为:用
sorted(c.items(), key=lambda x: x[1], reverse=True)[:3]更可控 -
c.most_common()不传参时返回全部,性能差(O(n log n)),大数据量慎用
另外,Counter 对负数计数不做限制,但 elements() 只产出正计数项——这点常被忽略,导致遍历时“消失”了减过次数的 key。
Modoer 是一款以本地分享,多功能的点评网站管理系统。采用 PHP+MYSQL 开发设计,开放全部源代码。因具有非凡的访问速度和卓越的负载能力而深受国内外朋友的喜爱,不局限于商铺类点评,真正实现了多类型的点评,可以让您的网站点评任何事与物,同时增加产品模块,也更好的网站产品在网站上展示。Modoer点评系统 2.5 Build 20110710更新列表1.同步 旗舰版系统框架2.增加 限制图片
namedtuple 是不可变对象,_replace() 才是修改入口
定义 Point = namedtuple('Point', ['x', 'y']) 后,p = Point(1, 2) 的字段不能直接赋值:p.x = 3 会触发 AttributeError。
修改唯一合法方式是 _replace():
-
p._replace(x=3)返回新实例,原p不变 - 只接受关键字参数,不支持位置传参;未提供的字段保持原值
- 字段名含下划线(如
_id)会被自动过滤,除非显式设rename=True
注意:_replace() 不校验类型或范围,也不会触发任何钩子——它就是浅拷贝+字典更新。如果需要验证逻辑,应封装成普通 class,别硬套 namedtuple。
deque 的 maxlen 参数会静默丢弃旧元素,不是警告或报错
初始化 d = deque(maxlen=3) 后,持续 append() 超过容量时,左端元素被自动踢出,不抛异常也不提示。
这在滑动窗口类场景很实用,但也容易埋坑:
- 调试时发现数据“变少”,却没意识到是
maxlen在起作用 - 想检测是否发生截断?得自己维护长度对比:
if len(d) == d.maxlen and len(d) > 0: -
extend()一次性加多个时,同样受maxlen约束,但行为是“整体插入后截断”,不是逐个判断
真正需要“满则报错”的场景,别用 deque,改用普通 list + 显式长度检查更清晰。









