为什么这个列表要更改它的所有值,因为它唯一的修改时间是通过 .append()?

Why is this list changing all of its values since the only time it is modified is through .append()?

我正在尝试通过附加布尔值列表的动态“实例”并在所有索引值的最高索引值处迭代 True 值来生成给定位数的所有可能二进制排列的数组它后面的位置。它的目的是将给定数量的开关的全部或部分排列编码为一种格式,该格式可以绑定到一个或一对 base-36 数字,并编码为一个字符串以作为保存文件记录。

当这个迭代True到达最后一个或'omega'位置时,它被关闭并添加到'omegaStack'; 'instance' 中具有最高索引值的 True 值也向上移动一位。如果堆栈中有任何值,则在实例上调用枚举方法以查找 'instance'.

中 True 值的最高索引位置

如果 omegaStack 前面没有要填充的 True 值,它应该用一个额外的 True 清空到 alphaStack 中,以从 [0] 位置向上填充实例并开始迭代最高索引中的 True再次在列表中的位置。

如果omegaStack将True值放入'instance'中的最终索引位置,在将实例追加到数组后,它会搜索任何相邻的True值并将它们全部放入堆栈中再次填充到从枚举(实例)中读取 True 的最高索引位置(+1)。

这会导致在指定大小的列表中不断增加和推进“打开”开关数量的级联效应。

像这样: x, o 为 False, True

makeSwitchTable(4)

应该打印

[[ x , x , x , x ],
[ o , x , x , x ],
[ x , o , x , x ],
[ x , x , o , x ],
[ x , x , x , o ],
[ o , o , x , x ],
[ o , x , o , x ],
[ o , x , x , o ],
[ x , o , o , x ],
[ x , o , x , o ],
[ x , x , o , o ],
[ o , o , o , x ],
[ o , o , x , o ],
[ o , x , o , o ],
[ x , o , o , o ],
[ o , o , o , o ]]

...是我应该得到的...

我得到的是这个可怕的疯狂循环,只有第一个全假实例是正确的。每隔一次调用 .append() 时,它会将 table[1:] 中的每个列表更改为应该添加到末尾的相同内容。

我很茫然。我以前从来没有在网上问过关于编码的问题,因为我发现有点耐力和研究往往会在不传播它的情况下充分指出我的愚蠢,但我很困惑,我不知道如何 google 这个。我知道我的代码可能不仅仅是附加的问题,但就我的大脑可以遵循的逻辑而言,它应该可以工作。显然不是。我也知道代码不是很简单,但如果我知道如何区分问题,我就不会问这个问题了。

这是我的代码。

def iTrack(instance):
    return [i for i, x in enumerate(instance) if x]


def makeSwitchTable(num):
    table = []
    allOff = [False for x in range(num)]
    end = [True for x in range(num)]
    table.append(allOff)
    instance = [False for x in range(num)]
    instance[0] = True
    table.append(instance)
    alphaStack = []
    iCheck = (iTrack(instance))
    omegaCounter = 0
    omegaStack = []
    print(table)
    for i in range(num):
        
        while omegaCounter < num:
            alphaCheck = len(alphaStack)
            omegaCheck = len(omegaStack)
            if alphaCheck:
                # populate from start
                print(instance, 'alpha')
                for sw in range(alphaCheck):
                    # populate
                    instance[sw] = alphaStack.pop(-1)
                    iCheck = (iTrack(instance))
                table.append(instance)
                if instance == end:
                    # should end the whole shebang if \
                    # the last instance appended == end
                    break
            elif omegaCheck:
                # populate from end
                print(instance, omegaStack, 'omega')
                for sw in range(omegaCheck):
                    # if there are trues left in instance
                    if iCheck:
                        # populate in front of the highest indexed True
                        instance[(iCheck[-1]+1)] = omegaStack.pop(-1)
                        iCheck = (iTrack(instance))
                    else:
                        # add an extra True to iterate
                        omegaCounter += 1
                        omegaStack.append(True)
                        for x in range(len(omegaStack)):
                            # pass omegaStack to alphaStack
                            print(omegaStack)
                            alphaStack.append(omegaStack.pop(-1))
                table.append(instance)
                print(instance, 'there')
                # if populate starts cascade
                if instance[-1]:
                    for sw in range(omegaCounter):
                        print('here')
                        # checks for adjacent Trues from end
                        if instance[-(sw+1)]:
                            # pop to the stack
                            instance[-(sw+1)] = False
                            omegaStack.append(True)
                        else:
                            # ends when no more adjacent to populate again
                            break
                    iCheck = (iTrack(instance))
            else:
                # iterate through last True in instance
                print(iCheck)
                instance[iCheck[-1]+1] = True
                instance[iCheck[-1]] = False
                print(instance, 'move')
                print(table)
                table.append(instance)
                # if it is in the final index position
                if instance[-1]:
                    # if first time through
                    if omegaCounter < 1:
                        omegaCounter += 1
                    # pop True into omegaStack
                    instance[-1] = False
                    omegaStack.append(True)
                    # if there is another True in instance
                    if len(iCheck) > 1:
                        # move it forward one spot
                        instance[iCheck[-2]+1] = True
                        instance[iCheck[-2]] = False
                    iCheck = (iTrack(instance))
                else:
                    iCheck = (iTrack(instance))
                
    print(table)
    
makeSwitchTable(4)

对于这位业余爱好者的任何帮助,我们将不胜感激。谢谢你的时间。

您的table 包含很多对相同 instance 的引用。当您继续修改 instance 时,它会影响所有引用。只需更改所有出现的以下行:

table.append(instance)

table.append(instance[:])

这将改为附加浅拷贝。