
Python里用set()去重为什么有时不生效
因为set()只支持不可变类型,对含列表、字典等可变对象的嵌套结构直接报错:TypeError: unhashable type: ‘list’。这不是bug,是集合底层哈希机制决定的。
纯数字、字符串、元组(且内部全不可变)可直接set()去重含list或dict的元素必须先转成可哈希形式,比如tuple(sorted(d.items()))自定义类需实现__hash__和__eq__才可进set去重后顺序不保留——set无序,如需保序得配合dict.fromkeys()
set交集&、并集|、差集-的实际行为差异
符号运算符和方法调用(如.intersection())看似等价,但参数类型和空值处理不同:符号操作要求两边都是set,而方法支持任意可迭代对象,且能链式调用。
{1,2} & [2,3] → 报错;{1,2}.intersection([2,3]) → 正常返回{2}{1,2} – {2,3} – {3}从左到右计算,等价于({1,2} – {2,3}) – {3},结果是{1}.difference()接受多个参数:s.difference(a, b)等价于s – a – b空set参与运算不会报错,但set().intersection([])返回空set,不是None
用set做成员判断比list快多少
平均时间复杂度从O(n)降到O(1),但实际提升取决于数据规模和哈希冲突。小列表(in查可能更快,因为set构造本身有开销。
重复查询场景(如过滤大量数据)一定先转set,比如blacklist_set = set(blacklist)再循环判断单次判断+小数据量,别为“理论上快”强行转set,反而多一次遍历frozenset适合当字典键或传入函数作只读集合,避免意外修改注意内存:set比list内存占用高约3–5倍,大数据量要权衡
字符串转set去重后为什么顺序乱了
set(‘hello’)得到{‘h’, ‘e’, ‘l’, ‘o’} ,是因为set不保证插入顺序——这是语言规范,不是版本问题。3.7+的dict有序,但set没跟上。
立即学习“Python免费学习笔记(深入)”;
需要保序去重,用dict.fromkeys(‘hello’).keys(),结果是dict_keys([‘h’, ‘e’, ‘l’, ‘o’])转成list时显式排序:sorted(set(s)),但这是按字符ASCII排,不是原顺序collections.OrderedDict.fromkeys()在3.7前可用,现在基本被dict.fromkeys()替代别依赖set输出顺序做逻辑判断,哪怕本地测试看起来“刚好有序”
真正容易被忽略的是:集合运算结果是新set,原集合不变;但.update()、.difference_update()这类带_update的方法会就地修改。混用时一不留神就改掉原始数据。

评论(0)