我年纪大了,没有头发可以拔掉。我已经阅读了与我在SO上可以找到的类似问题的答案。我有以下代码:
a = [[1,2],[3,4],[4,5]]
b = ['a','b','c']
print('a:',a)
print('b:',b)
c = a[:]
print('c == a:', c==a)
print('c is a:',c is a)
print('id(c) = id(a):', id(c)==id(a))
[x.extend(b) for x in c]
print('c after:',c)
print('a after:',a)`
输出是:
a: [[1, 2], [3, 4], [4, 5]]
b: ['a', 'b', 'c']
c == a: True
c is a: False
id(c) = id(a): False
c after: [[1, 2, 'a', 'b', 'c'], [3, 4, 'a', 'b', 'c'], [4, 5, 'a', 'b', 'c']]
a after: [[1, 2, 'a', 'b', 'c'], [3, 4, 'a', 'b', 'c'], [4, 5, 'a', 'b', 'c']]
我正在寻找显示为'c after:'的结果但是我不明白为什么a也被修改了?! 我也试过
c = list(a)
和
c = copy.copy(a)
当然,简单的c = a不能按预期工作。 我错过了什么?! 谢谢。
答案 0 :(得分:7)
这是因为您没有复制列表中的元素。不复制a
内的列表。因此,extend
方法会影响两个列表中的元素。您应该使用c = copy.deepcopy(a)
来复制嵌套元素。
答案 1 :(得分:1)
尝试像这样分配c列表,(没有.copy()解决方案)
c = []
for elem in a:
c.append(list(elem))
或带有列表理解的一个班轮
c = [list(elem) for elem in a]
如果列表中有列表,则提供深层副本,当然不是3层。
你失败的原因是你设法正确地复制了列表,但里面的列表仍然重新启用了相同的内存值,因此元素列表中没有副本。此解决方案还复制内部列表,这是deepcopy的定义。
答案 2 :(得分:0)
正如其他海报所解释的那样,A中的列表实际上并没有复制到C - 它们只是对原始列表的引用。您可以在运行以下代码时看到:
num_lists = [[1,2],[3,4],[4,5]]
lists_copy = num_lists[:]
orig_first = num_lists[0]
copy_first = lists_copy[0]
print('Are the first elements the same object?', orig_first is copy_first)
打印“True”,意味着[1,2]里面的lists_copy实际上是来自num_lists的[1,2]。复制Python列表太复杂了,我希望他们将其更改为将来更友好。截至目前,您可以做的最好的事情是:
lists_copy = copy.deepcopy(num_lists)
您可以在下方看到它:
from copy import deepcopy
lists_copy = deepcopy(num_lists)
orig_first = num_lists[0]
copy_first = lists_copy[0]
print('Are they they the same after copying with deepcopy?', orig_first is copy_first)
此代码打印“False”,表示列表已安全复制,并且余额最终还原到Universe:)
答案 3 :(得分:0)
还要考虑列表是可变类型,可以在创建后修改,与不可变类型(例如字符串)形成对比。不可变类型在创建后无法更改。因此,如果您尝试向其附加第二个字符串,则会生成字符串的真实副本。可变类型可以更改。因此,不进行复制,并且a和c都引用相同的列表。