python中[[]] * (n)和[[] for _ in range(n)]的区别详解
作者:Smart_Maggie
1、现象
刷leetcode207的时候碰到一个坑,用[[]] * (n)初始化二维数组,逻辑是正确的,但是结果始终不对。
2、原因
最后定位是初始化语句使用错误导致的,我使用的是[[]] * (n),应该使用[[] for _ in range(n)]
3、解释
[[]] * (n)和[[] for _ in range(n)]打印结果完全一样,但是原理却不一样
[[]] * (n)表示复制子列表( 此处为[] ) n次,这些子列表指向或引用相同的对象,也就是内存地址一样,因此修改其中一个子列表元素,会同时影响其他子列表的值,如下面代码中的L1
[[] for _ in range(n)] 表示列表的子列表元素是每次for循环创建的新对象,这些子列表指向或引用不同的对象,内存地址当然也不一样,因此修改其中一个子列表元素,不会影响其他子列表的值,如下面代码中的L2
n = 2 L1 = [[]] * n L2 = [[] for _ in range(n)] print(f'L1:{L1}, L2:{L2}') print(L2 == L2) #值相等 print(id(L1[0]),id(L1[1])) # L1列表内的元素,地址相同 print(id(L2[0]),id(L2[1])) # L2列表内的元素,地址不同 L1[0].append(1) L2[0].append(1) print(f'L1:{L1}, L2:{L2}')
打印结果:
4、注意
L1 中的元素是列表,是可变对象,使用*n复制,不同元素才会指向同一个对象,但是如果L1中元素是不可变对象,比如int、string、float、tuple,使用*n复制的时候,不同元素也会指向同一个元素,但是修改时,由于是不可变对象,修改时会重新开辟一块内存,变量指向新地址,这样修改其中一个元素,不会影响其他元素
i = 2 L1 = [2] * i # 列表元素为不可变对象 int print(L1) print(id(L1[0]),id(L1[1])) L1[0] = 4 print(id(L1[0]),id(L1[1])) print(L1)
打印结果为
5、其他
可变数据类型:列表list[ ]、字典dict{ }
不可变数据类型:整型int、字符串str' '、元组tuple()浮点数float
到此这篇关于python中[[]] * (n)和[[] for _ in range(n)]的区别详解的文章就介绍到这了,更多相关python [[]] * (n)和[[] for _ in range(n)]内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!