0

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

  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 = []
4

5 回答 5

2

gap_in_y如果不查看和是如何创建的,就很难判断gap_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,那么您知道您在两个嵌套列表中都有相同列表的副本。

于 2012-10-01T23:56:13.760 回答
0

当你这样做时:

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

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

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

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

(假设new是一个列表)。

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

于 2012-10-02T00:40:02.853 回答
0

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

于 2012-10-02T00:42:40.590 回答
0

不是追加 new,而是追加 new[:],这将为每个 gap_in_* 创建一个 new 副本,就像您现在拥有的那样,它将相同的列表放入每个 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 = []
于 2012-10-02T03:18:53.103 回答
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/As 是否引用同一个对象并不重要,因为该对象无法修改。

于 2012-10-02T03:37:46.397 回答