我的代码的简化版本:
sequence = [['WT_1', 'AAAAAAAA'], ['WT_2', 'BBBBBBB']]
def speciate(sequence):
lineage_1 = []
lineage_2 = []
for i in sequence:
lineage_1.append(i)
for k in sequence:
lineage_2.append(k)
lineage_1[0][0] = 'L1_A'
lineage_1[1][0] = 'L1_B'
lineage_2[0][0] = 'L2_A'
lineage_2[1][0] = 'L2_B'
print lineage_1
print lineage_2
speciate(sequence)
输出:
[['L2_A', 'AAAAAAAA'], ['L2_B','BBBBBBB']]
[['L2_A','AAAAAAAA'], ['L2_B','BBBBBBB']]
当我希望得到这个时:
[['L1_A', 'AAAAAAAA'], ['L1_B','BBBBBBB']]
[['L2_A','AAAAAAAA'], ['L2_B','BBBBBBB']]
有人知道问题是什么吗?
答案 0 :(得分:2)
当你追加时,你必须做一个深拷贝(或者在这种情况下是浅拷贝)。否则lineage_1[0][0]
和lineage_2[0][0]
引用相同的对象。
from copy import deepcopy
for i in sequence:
lineage_1.append(deepcopy(i))
for k in sequence:
lineage_2.append(deepcopy(k))
答案 1 :(得分:1)
您要在for循环中附加列表对象 - 相同列表对象(sequence[0]
)。
因此,当您修改该列表的第一个元素时:
lineage_1[0][0] = 'L1_A'
lineage_1[1][0] = 'L1_B'
lineage_2[0][0] = 'L2_A'
lineage_2[1][0] = 'L2_B'
您看到它在lineage_X
列表中都显示为已修改,其中包含sequence[0]
中列表的副本。
做类似的事情:
import copy
for i in sequence:
lineage_1.append(copy.copy(i))
for k in sequence:
lineage_2.append(copy.copy(k))
这将复制sequence
的子列表,以便您不会出现此别名问题。 (如果真实代码具有更深的嵌套,则可以使用copy.deepcopy
代替copy.copy
。)
答案 2 :(得分:0)
考虑这个简单的例子:
>>> aa = [1, 2, 3]
>>> bb = aa
>>> bb[0] = 999
>>> aa
[999, 2, 3]
这里发生了什么?
“名称”,例如aa
和bb
,只需引用列表,即同一列表。因此,当您通过bb
更改列表时,aa
也会看到它。使用id
显示了这一点:
>>> id(aa)
32343984
>>> id(bb)
32343984
现在,这正是您的代码中发生的事情:
for i in sequence:
lineage_1.append(i)
for k in sequence:
lineage_2.append(k)
您将相同列表的引用附加到lineage_1
和lineage_2
。