我希望输出像[[0,0,0,0,],[0,1,0,0],[0,2,0,0],[0,3,0,0]]

时间:2018-08-08 07:37:46

标签: python list loops nested-lists assign

time_count = [[0, 0, 0, 0]] * 4
j = 0
for i in range(len(time_count)):
    time_count[i][1] = j
    j += 1
print(time_count)

输出:

[[0, 3, 0, 0], [0, 3, 0, 0], [0, 3, 0, 0], [0, 3, 0, 0]]

我希望输出如下:

[[0,0,0,0],[0,1,0,0],[0,2,0,0],[0,3,0,0]] 

有人可以解释为什么每个index[1]都是3吗?

5 个答案:

答案 0 :(得分:4)

轻松修复:

time_count = [[0, 0, 0, 0] for _ in range(4)]

正如Klaus D.所说,在嵌套列表上使用*运算符通常是一个坏主意,因为它通过复制引用来复制内容。当乘以不可变类型的序列时,例如,您不会注意到这一点。整数列表,但是当元素可变时,就会得到重复项。

答案 1 :(得分:2)

将列表写为[[0,0,0,0]] * 4不好。列表是可变的。每次更改任何列表元素时,其所有副本都会更改。编写的一种好方法如下所示,因为这样就不会复制列表元素。

[[0, 0, 0, 0] for i in range(4)]

答案 2 :(得分:1)

要做:

time_count = [[0, 0, 0, 0]] * 4
print([[v if x!=1 else i for x,v in enumerate(a)] for i,a in enumerate(time_count)])

输出:

[[0, 0, 0, 0], [0, 1, 0, 0], [0, 2, 0, 0], [0, 3, 0, 0]]

更新:

说明:

  1. 使用enumerate遍历列表time_count的索引和值。

  2. 再次使用enumerate遍历列表a的索引和值。 time_count 的迭代器。

  3. 通过a的索引并说itime_count的索引迭代器),如果xa的索引迭代器)为1,否则说va的迭代器)

注意:这全部在列表理解中

答案 3 :(得分:1)

*运算符仅创建对原始列表的新引用(此处为[0, 0, 0, 0])。

如果将原始列表更改为time_count[i][1] = j,则所有引用均反映相同的更改。

如果要创建新列表,则可以在带有循环的扩展方法上使用:

time_count = []
time_count.extend([0,0,0,0] for _ in range(4))

现在,time_count中的所有元素列表都存储单独的内存,并且可以具有不同的值。

答案 4 :(得分:1)

基本上,列表的实体是指向特定内存位置的指针。当将列表(a)分配给列表(b)时,表示列表(b)指向与列表(a)相同的存储位置。

 a = [1, 2, 3]
 b = a
 a = [3, 4, 5]
 print(a, b)

 [3, 4, 5] [1, 2, 3]

在上述问题中,如果嵌套列表的内部乘以4倍,则所有子列表都指向相同的内存位置。因此,如果子列表之一被更改,则更改将传播到所有子列表,这在代码执行时基本上会产生意外的结果。对于任何有兴趣了解更多的人, 该视频总结了列表中不明显的所有基本功能。它还进一步详细解释了上述问题。 https://www.youtube.com/watch?v=_AEJHKGk9ns