Python 3.5列表理解修改原始

时间:2015-12-21 21:20:35

标签: python list object reference list-comprehension

我年纪大了,没有头发可以拔掉。我已经阅读了与我在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不能按预期工作。 我错过了什么?! 谢谢。

4 个答案:

答案 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都引用相同的列表。