Python 看似等价的列表初始化会导致不同的行为
我正在用Python 3解决问题,并提出了以下解决方案: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])
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只计算[]一次。因此,只创建一个实例