我已经尝试使用两种不同的方法在Python 3.7中创建多维列表。但是他们的行为有所不同,我感到困惑。
我已经尝试创建8 * 2 * 1 * 29多维数组。第一个是使用复制,如下所示:
arrayToCreate = [[[[-1]* 29]*1] *2] *8
第二个重复:
arrayToCreate = [[[[-1 for x in range(0,29)] for y in range(0,1)] for x in range(0,2)] for t in range(0,8)]
当我将值分配给某个位置时,似乎它们以第一种方式被复制8次,而在第二种版本中则没有。我的问题在于,很难理解为什么创建副本以及为什么仅在第一维创建副本。
例如,如果我设置了
arrayToCreate[0][0][0][3]= 4445
我得到的第一个版本的结果是:
[[[[-1, -1, -1, 4445, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]],
[[-1, -1, -1, 4445, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]]],
[[[-1, -1, -1, 4445, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]],
[[-1, -1, -1, 4445, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]]],
[[[-1, -1, -1, 4445, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]],
[[-1, -1, -1, 4445, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]]],
[[[-1, -1, -1, 4445, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]],
[[-1, -1, -1, 4445, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]]],
[[[-1, -1, -1, 4445, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]],
[[-1, -1, -1, 4445, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]]],
[[[-1, -1, -1, 4445, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]],
[[-1, -1, -1, 4445, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]]],
[[[-1, -1, -1, 4445, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]],
[[-1, -1, -1, 4445, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]]],
[[[-1, -1, -1, 4445, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]],
[[-1, -1, -1, 4445, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]]]]
感谢您的帮助。
发生的情况是,在第一种技术中,内部列表作为外部列表中的元素被共享。换句话说,所有列表元素实际上都指向相同的数据值。
为简单起见,我们有这个:
table1 = [[0] * 4] * 4
这实际上等效于此分解版本:
row = [0] * 4
table1 = row * 4
输出:
[[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]]
或
[row,
row,
row,
row]
因此,该表中的所有行实际上都是相同的数据,执行table[0][0] = 1
等同于执行row[0] = 1
,因此修改了所有行。
列表理解不会发生这种情况的原因是它正在创建新行:
table2 = [[0 for _ in range(4)] for _ in range(4)]
这等效于此展开的版本:
table2 = [[0 for _ in range(4)],
[0 for _ in range(4)],
[0 for _ in range(4)],
[0 for _ in range(4)]]
或
table2 = [row1,
row2,
row3,
row4]
因此评估table2[0][0] = 1
仅修改row1
。
...为什么只在第一维。
它实际上在各处创建了副本:
table3 = [[[0] * 2] * 2] * 2
# Set the first element of every innermost list
table3[0][0][0] = 1
# [[[1, 0], [1, 0]],
# [[1, 0], [1, 0]]]
# Set the first innermost list itself in its "parent" list
table3[0][0] = 1
# [[1, [1, 0]],
# [1, [1, 0]]]