列表推导式内用set是否低效?为何diff2比diff1性能更优?
列表有序差集的效率差异解惑
你疑惑的核心点正是两种实现效率差的关键:diff1里的
set(b)根本不是只计算一次,而是列表推导式每遍历a中的一个元素,就会重新执行一次set(b)的构建。原因很直白:Python列表推导式在执行时,条件判断部分的
set(b)属于每次迭代都要重新求值的表达式。比如a有1000个元素,那set(b)就会被重复创建1000次——每次遍历a的元素时,都会把b重新转成集合,这中间的重复创建开销直接拉低了效率。而diff2的写法是先把
b转成集合一次,之后整个列表推导式都复用这个已经建好的集合,每次成员判断都是O(1)的高效操作,自然比diff1快得多。你可以用一段简单的代码验证这个重复执行的问题:
b = [1, 2, 3] def rebuild_set(): print("正在构建set(b)") return set(b) a = [4, 5, 1, 6] diff1 = [x for x in a if x not in rebuild_set()]
运行这段代码会看到,"正在构建set(b)"会打印4次,正好对应a的元素个数,直接证明了每次迭代都在重新生成集合。
- 简单说:Python不会自动帮你把推导式里的重复计算提取到外面,想要只构建一次集合,就得像diff2那样手动把
set(b)的创建移到列表推导式之外。
内容的提问来源于stack exchange,提问作者LetMeSOThat4U
相关产品推荐
相关产品推荐

