Что определяет, будет ли переменная изменена или нет? - PullRequest
1 голос
/ 05 августа 2020
class MyClass:
    def __init__(self, a):
        self.a = a

def append(some_list):
    some_list.append(["d"])
    
foo =[["a"],["b"],["c"]]
bar = foo
my_class = MyClass(foo)

append(bar)

for item in bar:
    item[0] += "x"
    letters = item[0]
    letters += "z"
print (my_class.a)

Дает результат

[['ax'], ['bx'], ['cx'], ['dx']]

В этом примере происходит довольно много всего, и я чувствую себя довольно хорошо обо всем, за исключением того, что я ожидал, что «z» будет помечен на строки тоже, но это не так.

Может кто-нибудь объяснить, почему имеет смысл не включать «z» в строки?

Я думал, что индексация вернет «контейнер» со строкой а затем добавление «z» изменит сохраненную строку. По-видимому, создается отдельный «контейнер», но я не понимаю, как и почему.

(Если добавление к строке создает новую строку, я не знаю, почему такое же поведение будет происходить и с целыми числами. который я тестировал ... Будет ли использование float другого результата?)

1 Ответ

1 голос
/ 05 августа 2020

Это из-за изменяемого объекта. Например,

>>>l1 = [1,2,3]
>>>l2 = l1
>>>l2[0]=4
>>>print(l1[0])
4

В этом примере l1 и l2 указывают на одну и ту же ячейку памяти. Чтобы создать l1 как копию l2, используйте copy():

>>>l1 = [1,2,3]
>>>l2 = l1.copy()
>>>l2[0]=4
>>>print(l1[0]) 
1
>>>print(l2[0])
4

EDIT: измените объяснение в качестве предложенного комментария.

В вашем примере foo и bar указывает на ту же ячейку памяти: то, что вы изменяете в foo, также изменяется в bar. Почему он не добавляет "z", потому что letters - это объявленная переменная, имеющая значение item[0], но не изменяющаяся. Если вы print(letters), он напечатает "dz".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...