Python中[0] * n 描述的意思是什么?
如题,为何结果是[0,0,0,0,0,0,0,0,0]
Python中[0] * n 描述的意思是什么?
list * int 意思是将数组重复 int 次并依次连接形成一个新数组
[0] * n 在Python里是创建一个包含 n 个 0 的列表。n 是整数,结果就是一个长度为 n、每个元素都是 0 的新列表。
比如:
n = 5
my_list = [0] * n
print(my_list) # 输出: [0, 0, 0, 0, 0]
这里的关键是列表的乘法操作:[0] 这个单元素列表乘以 n,Python会把它复制 n 次然后拼接起来。所以 [0] * 3 得到 [0, 0, 0]。
注意,如果列表元素是可变对象(比如另一个列表),乘法复制的是引用,不是深拷贝:
matrix = [[0]] * 3
print(matrix) # 输出: [[0], [0], [0]]
matrix[0][0] = 99
print(matrix) # 输出: [[99], [99], [99]] # 所有子列表都变了,因为它们是同一个对象
要避免这个问题,可以用列表推导式:
matrix = [[0] for _ in range(3)]
简单说,[0] * n 就是快速创建全零列表的常用写法。
提醒一下有个坑:
>>> items = [{}] * 10
>>> items[0][‘key’] = ‘value’
>>> print(items)
谢谢两位
感觉不是坑 是很正常的对象引用 原对象变化了 引用的对象自然发生了变化 js 里这种情况才是常态 当然我 python 不是很熟
#4
有一次我这样初始化一个列表:
items = [{} for i in range(10)]
然后发现貌似可以这样写:
items = [{}] * 10
结果出现很诡异的 Bug,印象深刻
这个很正常,Mutable 对象都是按引用传递的:
a = {}
b = a
a[‘1’] = 1
print(b)
跟这个是一个道理。
同理还有定义函数的时候:
def foo(bar=[]):
bar.append(1)
print(bar)
foo()
foo()
bar 这个默认参数是会改变的,因为默认参数的值也是对该数组的引用
应该这样写
items[0] = {‘key’:‘value’}
相当于初始化一个长度为 n,每个元素的初始值都是 0 的list。貌似这是 Python 初始化 /预分配有较多元素的list的常用做法,貌似也是唯一的做法(有知道其他做法的朋友请分享一下)。
感觉上等同于 C++的<br>vector<int> tmp(n, 0)<br>
(但其实我不了解 C++的标准库,不知道说得对不对)
正如 2L 所说,需要注意,如果要初始化的list中的的元素是其他 container 类型(比如list、set、dict等,但不包括tuple,tuple本身是不可变的,不实用于这里),因为 Python 中所有东西都是类的概念,变量其实类似于 Java/C++中的引用变量。如果要初始化一个 10*10 全是 0 的二位数组,所以如果按照<br>l = [[0] * 10] * 10<br>l[0][0]=1<br>print(l)<br>
来初始化一个 2 维的list,你会“惊喜”地发现l中的每个元素都是指向同一个list对象。所以正确的做法是:<br>l = [[0] * 10 for _ in range(10)]<br>
说到这里,真心想给《 Fluent Python 》打个广告,这个问题和之前看到的另外一个对tuple进行+=操作的问题,其实都在《 Fluent Python 》中有详细讲解,看完之后有种恍然大悟的感觉。。。。。。然而我还没看完。。。。。。貌似最近中文翻译版也要发布了
这个主要是 mutable 复制时的问题吧。
#9 这里不是复制,list 里面的元素都是同一个对象。mutable 对象复制应该是 copy 和 deepcopy 的问题。
#2 浅拷贝

