Python附加功能未按预期工作

时间:2019-04-26 05:22:56

标签: python python-3.x list

>>> a = [1,2,3]
>>> b = []
>>> b.append(a)
>>> print(b)
[[1, 2, 3]]
>>> num = a.pop(0)
>>> a.append(num)
>>> print(a)
[2, 3, 1]
>>> b.append(a)
>>> print(b)
[[2, 3, 1], [2, 3, 1]]
>>> 

为什么会发生这种情况以及如何解决?我需要像这样的列表

[[1, 2, 3], [2, 3, 1]]

谢谢。

编辑:

还可以,为什么呢?

>>> a = []
>>> b = []
>>> a = [1,2,3]
>>> b.append(a)
>>> a = [1,2,3,4]
>>> b.append(a)
>>> print(b)
[[1, 2, 3], [1, 2, 3, 4]]
>>> 
'''

4 个答案:

答案 0 :(得分:2)

至少第一次添加列表a的副本。否则,您将两次都添加了相同的列表。

b.append(a[:])

答案 1 :(得分:1)

当您追加列表a时,python在列表b内创建对该变量的引用。因此,当您编辑列表a时,它会再次反映在列表b中。您需要创建变量的副本,然后将其附加以获得所需的结果。

答案 2 :(得分:0)

除了通过执行a[:]并将其分配给b来复制a之外。
您还可以使用collections.deque.rotate旋转列表

from collections import deque

a = [1,2,3]
#Make a deque of copy of a
b = deque(a[:])

#Rotate the deque
b.rotate(len(a)-1)

#Create the list and print it
print([a,list(b)])
#[[1, 2, 3], [2, 3, 1]]

答案 3 :(得分:0)

Python中的每个变量名称都应视为对一段数据的引用。在您的第一个清单中,b包含对同一基础对象的两个引用,该引用也由名称a引用。该对象通过您用于旋转其成员的操作而就地更改。当您查看对b中找到的对象的两个引用中的 时,或者实际上,当您查看与名称{{1}相关联的引用时,都会看到这种更改的效果。 }。

使用a函数可以看到它们的相同性:id()id(a)id(b[0])都返回相同的数字,这是基础列表的唯一标识符他们都引用的对象。或者,您可以使用id(b[1])运算符:is的值为b[0] is b[1]

通过对比,在第二个清单中,您重新分配 True-换句话说,通过使用赋值运算符a,您可以使该名称与其他名称相关联object:在这种情况下,您刚刚使用方括号括起来的文字表达式创建了一个新的=对象。 list仍然包含一个对旧列表的引用,现在您添加了一个新引用,指向这个不同的基础数据。因此,b的两个元素现在看起来互不相同-实际上它们是不同的对象,因此具有不同的b数字,其中只有一个与当前id()相同。 id(a)现在计算为b[0] is b[1]

如何解决?在更改名称之前,请重新分配名称False:例如,创建一个副本:

a

或:

a = list(a)

(或者您甚至可以使用import copy a = copy.copy(a) -研究差异)。或者,使用需要重新分配而不是就地更改的方法来旋转成员copy.deepcopy(),例如:

a

(NB {em>不可变对象,例如a = a[1:] + a[:1] 避免了整个混乱,这不是因为它们的行为方式根本不同,而是因为它们缺少产生就地更改的方法,因此迫使您使用重新分配策略。)