Функция добавления Python не работает должным образом - PullRequest
1 голос
/ 26 апреля 2019
>>> 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]]

Спасибо.

Edit:

Кроме того, почему это работает?

>>> 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 ]

2 голосов
/ 26 апреля 2019

Добавьте копию вашего списка a, по крайней мере, в первый раз. В противном случае вы добавили один и тот же список оба раза.

b.append(a[:])
1 голос
/ 26 апреля 2019

Когда вы добавляете список a, python создает ссылку на эту переменную внутри списка b. Поэтому, когда вы редактируете список a, он снова отражается в списке b. Вам нужно создать копию своей переменной и затем добавить ее, чтобы получить желаемый результат.

0 голосов
/ 26 апреля 2019

Каждое имя переменной в Python следует рассматривать как ссылку на часть данных.В вашем первом листинге b содержит две ссылки на один и тот же базовый объект, на который также ссылается имя a.Этот объект изменяется на месте с помощью операций, которые вы используете для вращения его членов.Эффект этого изменения виден, когда вы смотрите на или из двух ссылок на объект, найденный в b, или действительно, когда вы смотрите на ссылку, связанную с именем a.

Их идентичность можно увидеть с помощью функции id(): id(a), id(b[0]) и id(b[1]) все возвращают одно и то же число, которое является уникальным идентификатором базового объекта списка, на который они все ссылаютсяк.Или вы можете использовать оператор is: b[0] is b[1] оценивается как True.

Напротив, во втором листинге вы переназначаете a - другими словами, используя оператор присваивания =, вы связываете это имя с другим объектом:в этом случае новый 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, используя методы, которые влекут за собой переназначение, а не изменения на месте - например:

a = a[1:] + a[:1]

(NB неизменяемые объекты, такие как tuple, избегают всего этогопутаница - не потому, что они ведут себя принципиально иначе, а потому, что у них нет методов, которые производят изменения на месте и поэтому вынуждают вас использовать стратегии переназначения.)

0 голосов
/ 26 апреля 2019

В дополнение к созданию копии, выполнив a[:] и присвоив ее b.
Вы также можете использовать collection.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]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...