Note: When generating a list, it is better to use
[0 for _ in range(n)]
the method instead of[0] * n
the method for the following reasons.
Suppose we want to create a n = 2
list of length a
, there are two general methods: a = [0] * n
and a = [0 for _ in range(n)]
, there is no difference between the two methods when it is one-dimensional. But if we want to create a list, each element in the list is m = 3
a list of length The results of the two methods are different:
n, m = 2, 3
a = [[0] * n] * m # 用第一种方法生成的
# a = [[0, 0], [0, 0], [0, 0]]
b = [[0 for _ in range(n)] for _ in range(m)] # 用第二种方法生成的
# b = [[0, 0], [0, 0], [0, 0]]
a[0][0] = 1 # 令 a 列表的第一个元素为 1
# a = [[1, 0], [1, 0], [1, 0]]
b[0][0] = 1
# b = [[1, 0], [0, 0], [0, 0]]
Our expected result is like b
this, that is, the first element of the first list is equal to 1, but the list a
sets the first element of each list to 1.
The reason for this is that the first generation method is =
generated in a way similar to , that is, assuming that both a, b
are lists, we make a = b
that if one of them changes, the other will change accordingly, for example :
a = [0, 0, 0]
b = a
b[0] = 1
# a = [1, 0, 0]
# b = [1, 0, 0]
To avoid this situation, it should be written like this b = list(a)
.
Going back to the original question, if you use the first method a = [[0] * n] * m
, then the addresses stored in the lists a
in m
are the same, then if you change one of the lists, the other lists will change accordingly, and the above situation will appear.
c = [[0] * n for _ in range(m)] # 没问题
d = [[0 for _ in range(n)]] * m # 有问题
Therefore, it will be better to use all the lists to be generated in the future [0 for _ in range(n)]
.