You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中列表乘法与列表推导式初始化的差异探究

Python列表初始化:[0] * 20 vs 列表推导式的差异与底层逻辑

功能差异:分可变/不可变元素场景

如果初始化的是不可变元素(比如int、str、tuple),两种写法的结果完全一致——都会生成包含20个独立元素值的列表。但如果是可变元素(比如列表、字典),两者会产生本质区别:

  • [[]] * 20会生成20个指向同一个可变对象的引用,修改其中一个元素会影响所有元素;
  • 列表推导式[[] for _ in range(20)]会在每次循环中创建一个新的可变对象,所有元素都是独立的。

示例代码:

# 可变元素的差异对比
l_repeat = [[]] * 3
l_comp = [[] for _ in range(3)]

l_repeat[0].append(1)
print(l_repeat)  # 输出 [[1], [1], [1]]
print(l_comp)    # 输出 [[], [], []]

底层实现机制的核心区别

  • [0] * 20:C层面的序列重复
    这是Python内置的序列重复操作,全程在底层C代码中执行:直接计算所需内存大小,一次性分配连续内存块,然后将原元素的引用(对于不可变对象,复用引用安全且高效)复制指定次数填充到列表中。整个过程没有Python解释器层面的循环,完全是底层高效操作。

  • 列表推导式:Python层面的循环生成
    列表推导式本质是语法糖,背后会执行Python级别的循环逻辑:先创建range(20)迭代器,然后逐个遍历迭代器元素,每次循环都要执行元素表达式的求值(哪怕是简单的0,也会走Python的对象查找逻辑),再将结果添加到列表中。这个过程涉及Python解释器的循环调度、栈帧切换、迭代器调用等额外开销。

为什么LeetCode中[0] * 20更快?

LeetCode的运行环境对执行效率的细微差异非常敏感,[0] * 20的优势来自:

  • 无Python循环开销:全程由C底层完成,避免了Python迭代器的next()调用、循环变量赋值等冗余操作;
  • 内存分配更高效:一次性分配足够的连续内存,不需要像列表推导式那样逐步添加元素时可能触发的内存扩容;
  • 对象复用优化:对于不可变元素(比如0),[0] * 20直接复用同一个对象的引用,省去了每次循环创建对象的微小开销。

内容的提问来源于stack exchange,提问作者ZooPanda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 10:35:29