这个算是新手的常见问题吧,我上个礼拜刚给别人解答过。把上次写的直接粘贴复制过来。
>>>>
我补充一下, list 的乘法是浅拷贝,只是复制存储的 PyObject*指针,
所以 a = [[]]*2 ,如果 a[0].append(3), 就会得到[[3], [3]] 而不是[[3], []]
至于为什么这种效果,没办法,人家就是这样设计的,参见
https://hg.python.org/cpython/file/8f84942a0e40/Objects/abstract.c#l928上面会调用 list 的 sq_repeat , 也就是在这里,
https://hg.python.org/cpython/file/db93af6080e7/Objects/listobject.c#l539你看,它只是复制了指针。
其实我想补充的是,
对于 python 的多维数组,请不要这样写,
[[0 for i in xrange(4)] for j in xrange(4)],
既然 0 是 immutable ,你完全可以这样写
[[0]*4 for j in xrange(4)]
但是,注意到你都用不到 j 这个变量,我发现你用的是 python2, 在 python2 里, list comprehension 没有新开栈帧,用的是当前函数(或者 module,本质上是 PyFrame)的 local namespace, 换句话说,你这个 j 除了污染当前函数的 local 名字空间以外,别无是处。
建议这样写,
[[0]*4 for _ in xrange(4)]
当然,在 Python3 里, list comphrension 会在一个新的 frame 里执行,不会存在名字空间的污染,不过还是推荐写成_, 因为你根本用不到 j 这个变量。