Python中列表乘法与列表推导式创建嵌套列表的差异问题
Python嵌套列表两种初始化方式的差异说明
两种写法的核心区别在于子列表对象的创建逻辑完全不同,直接导致后续追加元素时的行为差异:
- 乘法初始化写法
count = [[]] * (len(nums) +1):*操作符在复制列表元素时,仅复制已有对象的内存引用,不会创建新的子列表对象。最终外层列表的所有索引位置,存储的都是指向同一个空列表的引用。此时执行count[val].append(key)本质是对全局唯一的那个子列表做原地修改,从外层列表的任意索引访问子列表,都会看到修改后的内容,表现为“所有子列表同步追加元素”。 - 列表推导式初始化写法
count = [[] for i in range(len(nums)+1)]:推导式每一轮迭代都会执行一次[]的实例化逻辑,总共生成len(nums)+1个完全独立、内存地址互不相同的空子列表。每个索引位置存储的是对应独立子列表的引用,修改某一个索引对应的子列表时,不会对其他子列表造成任何影响,运行逻辑符合预期。
你可以通过打印子列表的内存ID快速验证这个差异:
# 乘法初始化验证 count1 = [[]] * 3 print(id(count1[0]), id(count1[1]), id(count1[2])) # 三个ID完全一致,指向同一个列表对象 # 列表推导式初始化验证 count2 = [[] for _ in range(3)] print(id(count2[0]), id(count2[1]), id(count2[2])) # 三个ID互不相同,是三个独立的列表对象
触发行为差异的业务逻辑段如下:
count = [[]] * (len(nums) +1) count = [[] for i in range(len(nums)+1)] for key, val in myMap.items(): count[val].append(key)
注意:这个规律不止适用于嵌套列表,任何包含可变类型对象(字典、自定义类实例等)的列表用
*做乘法初始化时,都会遇到同类引用复用问题,初始化包含可变元素的多维列表时,优先选择列表推导式的写法。
内容的提问来源于stack exchange,提问作者JEBIN JOHN
相关产品推荐
相关产品推荐

