将值分配给列表的第一个索引时,为什么值会更改?

时间:2019-09-25 14:38:17

标签: python python-3.x list

当我将其分配给ThreeByThree列表的第一个(newImage)索引时,定义的函数[0][0]的返回值将更改并加1。但是,连续的分配是有效的。请查看我的打印报表结果

def boxBlur(image):
  lenVert = len(image)
  lenHorz = len(image[0])
  newImage = [[0] * (lenHorz - 2)] * (lenVert - 2)
  def ThreeByThree(a,b,image):
    k = 0
    total = 0
    for i in range(a, a + 3):
      for j in range(b, b + 3):
        k = image[i][j]
        total += k
    return int(total / 9)

  for i in range(0, lenVert - 2):
    for j in range(0, lenHorz - 2):
      print(ThreeByThree(i, j, image))
      newImage[i][j] = ThreeByThree(i, j, image)  # This is where the assignment goes wrong
  return newImage

image = [[7, 4, 0, 1], 
         [5, 6, 2, 2], 
         [6, 10, 7, 8], 
         [1, 4, 2, 0]]
print(boxBlur(image))

预期输出:

5
4
4
4
 [[5, 4], [4, 4]]

输出:

5
4
4
4
 [[4, 4], [4, 4]]

1 个答案:

答案 0 :(得分:1)

问题是您使用newImage运算符创建的*列表正在创建相互引用的子列表。结果,分配newImage[0][0]时实际上会更改newImage[1][0]的值,因为它们相互引用。例如:

newImage = [[0] * 2] * 2

newImage[0][0] = 5
print(newImage)
# [[5, 0], [5, 0]]

newImage[1][0] = 4
print(newImage)
# [[4, 0], [4, 0]]

相反,创建不带子列表相互引用的初始列表(由于它们是不可变的,您仍然可以使用*运算符将子列表中的整数值相乘)。

newImage = [[0] * (lenHorz - 2) for _ in range(lenVert - 2)]