Python 看似等价的列表初始化会导致不同的行为

Python 看似等价的列表初始化会导致不同的行为,python,python-3.x,Python,Python 3.x,我正在用Python 3解决问题,并提出了以下解决方案: def dynamicArray(n, queries): seqList = [[] for _ in range(n)] lastAnswer = 0 result = [] for query in queries: if query[0] == 1: seqList[(query[1] ^ lastAnswer) % n].append(query[2])

我正在用Python 3解决问题,并提出了以下解决方案:

def dynamicArray(n, queries):
    seqList = [[] for _ in range(n)]
    lastAnswer = 0
    result = []

    for query in queries:
        if query[0] == 1:
            seqList[(query[1] ^ lastAnswer) % n].append(query[2])
        elif query[0] == 2:
            seq = seqList[(query[1] ^ lastAnswer) % n]
            lastAnswer = seq[query[2] % len(seq)]
            result.append(lastAnswer)

    return result
这可以很好地工作并通过所有测试用例

问题是当我从以下内容更改seqList的初始化时:

seqList = [[] for _ in range(n)]
为此:

seqList = [[]] * n
然后所有的测试用例都失败了,我不知道为什么。代码中没有其他更改

我甚至创建了以下简单的测试用例,只是为了比较这些初始化方法的结果:

n = 3

a1 = [[]] * n
a2 = [[] for _ in range(n)]

print(a1)
print(a2)
print(a1 == a2)
结果如预期:

[[],[],[]

[[],[],[]

真的

如果有人能向我解释这种行为,我将不胜感激。

这:

seqList = [[]] * n
与此相同:

lst = []
seqList = [lst for _ in range(n)]
使用*创建列表时,Python不会进行任何复制。所有子列表引用相同的列表。所以这一行:

seqList[(query[1] ^ lastAnswer) % n].append(query[2])

附加到所有列表。

它可能与您显示的相同,直到这里:

n = 3

a1 = [[]] * n
a2 = [[] for _ in range(n)]

print(a1)
print(a2)
print(a1 == a2)
输出:

True
[['_'], ['_'], ['_']]
[['_'], [], []]
但这里的差异是显而易见的:

a1[0].append('_')
a2[0].append('_')
print(a1)
print(a2)
输出:

True
[['_'], ['_'], ['_']]
[['_'], [], []]
这是因为列表是可变的数据类型。这两种初始化样式的工作方式不同:第一种是编译器一次构建所有的初始化样式,因此速度更快,而第二种是增量构建。对于不可变的数据类型,您不会看到类似的情况。

方法1:

n = 5
seqList = [[] for _ in range(n)]
seqList
>>[[], [], [], [], []]

seqList[0].append(8)
seqList
>>[[8], [], [], [], []]
方法2:

seqList2 = [[]] * n
seqList2
>>[[], [], [], [], []]

seqList2[0].append(8)
seqList2
>>[[8], [8], [8], [8], [8]]
方法2创建一个列表列表,每个成员列表引用同一个列表实例

[[]for uu in range]为n的每次迭代计算或创建一次[],而[[]]*n只计算[]一次。因此,只创建一个实例