defaultdict通过指定默认工厂函数(如list、int)按需生成缺失键的值,避免KeyError;错误写法是传不可调用对象如[],正确写法为defaultdict(list)。

defaultdict 怎么避免键不存在时抛 KeyError
普通字典访问不存在的键会触发 KeyError,而 defaultdict 在初始化时指定默认工厂函数,能自动处理缺失键。关键不是“设个默认值”,而是“按需生成”——比如用 list 作工厂,每次遇到新键就新建一个空列表,而不是复用同一个对象。
- 错误写法:
defaultdict([])—— 这会报错,因为[]不是可调用对象 - 正确写法:
defaultdict(list)(注意没括号)、defaultdict(int)、defaultdict(lambda: "N/A") - 慎用可变默认值:若用
defaultdict(lambda: [])没问题,但若误写成defaultdict(lambda x=[]: x),会导致所有键共享同一列表
Counter 统计字符串/列表时怎么保留原始顺序
Counter 本身继承自 dict,在 Python 3.7+ 中保持插入顺序,但它的 most_common() 方法返回的是按频次排序的结果,不反映首次出现顺序。如果需要“先出现的优先,频次相同时按原序排”,得手动处理。
- 直接用
Counter(items).keys()可得去重后按首次出现顺序排列的元素(Python 3.7+) - 要实现“频次降序 + 首次出现升序”双条件排序:
sorted(Counter(items).items(), key=lambda x: (-x[1], items.index(x[0]))),但注意items.index效率低,大数据量建议预建索引映射 -
Counter支持减法(c1 - c2)和取正(+c),但负频次会被自动过滤掉,这点容易被忽略
namedtuple 定义后怎么安全地添加新字段
namedtuple 实例是不可变的,定义后无法动态加字段。所谓“添加字段”只能是创建新类型或转换为可变结构。强行用 _replace() 只能更新已有字段,不能新增。
- 若只是临时需要扩展,转成
dict最直接:my_tuple._asdict(),然后增删键 - 若需长期支持字段扩展,改用
types.SimpleNamespace或dataclass(Python 3.7+),它们天生支持属性赋值 - 用
namedtuple._fields + ("new_field",)拼接字段名再调用namedtuple重建类型,可行但破坏封装,且旧实例无法直接升级
deque 做队列时为什么 pop() 比 pop(0) 快得多
deque 是双向链表实现,pop() 和 popleft() 都是 O(1),但 pop(0) 是 list 的方法,而 list 是连续数组,删除首元素需整体前移,复杂度 O(n)。混用 deque 和 list 的操作习惯是常见性能陷阱。
Scala也是一种函数式语言,其函数也能当成值来使用。Scala提供了轻量级的语法用以定义匿名函数,支持高阶函数,允许嵌套多层函数,并支持柯里化 。Scala的Case Class及其内置的模式匹配相当于函数式编程语言中常用的代数类型(Algebraic Type)。 Scala课堂是Twitter启动的一系列讲座,用来帮助有经验的工程师成为高效的Scala 程序员。Scala是一种相对较新的语言,但借鉴了许多熟悉的概念。因此,课程中的讲座假设听众知道这些概念,并展示了如何在Scala中使用它们。我们发现
立即学习“Python免费学习笔记(深入)”;
- 别对
deque写d.pop(0)—— 虽然语法合法,但退化为慢路径,应改用d.popleft() -
deque(maxlen=N)启用最大长度后,append 会自动丢弃另一端元素,适合滑动窗口场景;但此时rotate()行为受 maxlen 影响,容易出意料 -
deque不支持切片(如d[1:3]),也不支持in查找(O(n)),高频查找请换回 list 或 set
实际用 collections 高阶功能时,最容易卡住的不是语法,而是对底层数据结构行为的误判——比如把 deque 当 list 用、把 namedtuple 当可变容器用、或者以为 Counter 的构造过程会保留输入顺序(其实只保证结果字典顺序,不等于输入顺序)。









