python数组值神秘地改变

时间:2012-10-01 23:47:22

标签: python arrays

我对以下行为感到非常困惑:

  gap_in_y[i][j] = max((scoreMatrix[i-1][j] - dy), (gap_in_y[i-1][j] - ey))
  if i == 3 and j == 1:
    print gap_in_y
  gap_in_x[i][j] = max((scoreMatrix[i][j-1] - dx), (gap_in_x[i][j-1] - ex))
  if i == 3 and j == 1:
    print gap_in_y

两个print语句生成的数组恰好只有一个值:gap_in_y[3][1]中包含的值。修改gap_in_x,一个单独的数组,不应该影响gap_in_y ...但是,不知怎的。

有什么想法吗?我一直在疯狂试图解决这个问题!

我按以下方式创建了两个数组:

for i in range (0, ALength+1):
    for j in range (0, BLength+1):
        new.append("N/A")
    gap_in_y.append(new)
    gap_in_x.append(new)
    new = []

5 个答案:

答案 0 :(得分:2)

如果没有看到gap_in_ygap_in_x是如何创建的,很难分辨,但这里可能发生的是gap_in_y[3]gap_in_x[3]都是对它们的引用列表,所以修改一个将修改另一个。您可以通过添加以下代码来检查:

if i == 3:
    print id(gap_in_y[3]) == id(gap_in_x[3])

如果这打印True,那么您就知道在两个嵌套列表中都有相同列表的副本。

答案 1 :(得分:0)

当你这样做时:

gap_in_x.append(new)
gap_in_y.append(new)

两个列表都将引用相同的对象new

最简单的解决方案可能是将其更改为:

gap_in_x.append(new[:])
gap_in_y.append(new[:])

(假设new是一个列表)。

切片运算符[:]将创建列表new的副本,以便每个列表都会收到自己的副本。

答案 2 :(得分:0)

我看到,在创建数组时,您创建了一个新列表,并将同一个列表附加到gap_in_xgap_in_y列表中。所以它们现在包含相同的列表,其中的任何突变都可以从父列表中自然看到。

答案 3 :(得分:0)

不是附加新的,附加新的[:],这将为每个gap_in_ *创建一个新的副本,就像现在一样,它会将相同的列表放入每个中。

for i in range (0, ALength+1):
    for j in range (0, BLength+1):
        new.append("N/A")
    gap_in_y.append(new[:])
    gap_in_x.append(new[:])
    new = []

答案 4 :(得分:0)

其他答案指出了当前代码的问题。我只是想建议一种创建列表的替代方法,使用列表乘法和列表推导而不是显式循环和append()

gap_in_x = [["N/A"] * (BLength + 1) for _ in range(ALength + 1)]
gap_in_y = [["N/A"] * (BLength + 1) for _ in range(ALength + 1)]

请注意,您不希望对外部列表使用列表乘法(例如[["N/A"] * BLength] * ALength),因为这会导致与您已经存在的问题类似的问题,其中所有内部列表都将是副本彼此之间(虽然这次是在同一个外部阵列中,而不是在两者之间)。它对内部列表很好,因为字符串是不可变的。一些(或所有)N/A引用相同的对象并不重要,因为该对象不能被修改。