咨询代码中红线圈注行的作用及可替代写法
红圈代码行说明
你标注的list(set(lst))是Python生态里非常经典的列表去重极简写法,各部分逻辑非常直白:
set(lst):将传入的列表对象转换为集合类型。集合是Python内置的无序容器,天生不允许存储重复元素,这一步会自动过滤掉列表里所有重复的值,只保留唯一值。list():将去重后的集合重新转换为列表类型,匹配函数返回列表的预期。
设计意图与使用原因
这行写法被广泛使用的核心原因有两个:
- 代码足够简洁:一行代码就能完成去重逻辑,不需要写循环、临时变量、重复判断的冗余代码。
- 性能足够优秀:集合的去重逻辑基于哈希表实现,整体时间复杂度为O(n),远高于手写双层循环判断元素是否已存在的O(n²)写法,在处理万级以上数据量时性能差距会非常明显。
需要注意这个写法的两个固有局限:
- 去重后会丢失原列表的元素顺序:Python3.7之前集合是完全无序的,3.7之后的CPython实现里集合虽然在部分场景下看起来保序,但Python官方并没有对集合的顺序做承诺,生产环境如果对元素顺序有强要求,不建议依赖这个写法。
- 要求列表内所有元素必须可哈希:如果列表里存在列表、字典这类不可哈希的元素,运行时会直接抛出
TypeError: unhashable type错误。
等价替代写法
可以根据实际场景选择不同的替代方案:
- 如果需要严格保留原列表的元素顺序(兼容Python3.7+),可以用字典去重的写法,性能和集合去重一致,且官方保证顺序:
res = list(dict.fromkeys(lst))
- 如果列表中存在不可哈希的元素(比如嵌套列表、字典),可以用遍历判断的写法,适合小数据量场景:
res = [] for item in lst: if item not in res: res.append(item)
- 如果后续不需要使用列表的索引、切片等特性,只是做成员判断、集合运算(交集、并集、差集),可以直接保留集合类型,省掉转列表的开销:
res = set(lst)
- 如果是Python3.5+版本,也可以用解包语法实现和
list(set(lst))完全等价的效果,写法更简洁:
res = [*set(lst)]
内容的提问来源于stack exchange,提问作者Tejas Agarwal
相关产品推荐
相关产品推荐

