Почему работа со списком дает разные результаты? - PullRequest
0 голосов
/ 01 февраля 2020

Итак, я делал алгоритм Якоби, чтобы приблизить решения системы уравнений, и я столкнулся с парой вещей, которые я не предпринимаю при работе со списком. Допустим, у меня есть эти три функции

def func1 (list):
    list_old = list
    list[0] = 99

    print(list_old)
    print(list)

def func2 (list):
    list_old = list.copy()
    list[0] = 99

    print(list_old)
    print(list)

def func3 (list):
    list_old = list
    list = [9,9,9]

    print(list_old)
    print(list)

list = [0,0,0]
func1(list)
func2(list)
func3(list)

Печать Func1

[99, 0, 0] # List_old
[99, 0, 0] # List

Печать Func2

[0, 0, 0] # List_old
[99, 0, 0] # List

Печать Func3

[0, 0, 0] # List_old
[9, 9, 9] # List

Так мои вопросы: 1) почему List [0] на func1 изменяет list_old? Я думаю, что это что-то с указателями и пространством памяти, но я не уверен, и я не нашел ничего, что объясняет это. 2) Почему в func3 list_old не изменяется? Разве не должно быть так же, как func1?

Ответы [ 2 ]

1 голос
/ 01 февраля 2020

В значительной степени то, что сказал @ггорлен, точно на месте. Способ работы python переменных, подобных спискам, заключается в том, что они хранятся в определенной точке c в памяти. Передав переменную списка в функцию, а затем изменив ее, вы изменяете ее по ее указанному c адресу в памяти, поэтому даже если вы, например, оставляете функцию func1, вы изменили свой исходный список, и вызовы к нему будут иметь эти изменения.

То, что вы делаете в func2 с .copy (), создает другой список в другой точке памяти. Таким образом, изменения в этом списке не повлияют на изменения вашего исходного списка и наоборот (более того, изменения в func1 все равно будут присутствовать в новом скопированном списке, потому что они были сделаны до копирования).

Теперь, чтобы ответить на ваш вопрос, в func1 list_old не совпадает со list_old в func2, имя переменной list_old является локальным для обеих функций func1 и func2 и указывает на разные списки. list_old в func1 указывает на исходный список, объявленный в первой строке кода вне ваших функций. list_old в func2 указывает на вновь созданную копию, эти две переменные разные. В func3 list_old = list присваивает list_old исходному списку, но тогда у вас есть list = [9,9,9], который создает новый список, поэтому имеет новый адрес в памяти. Так, list_old и list в func3 указывают на два разные места в памяти.

Вот хороший пост о переменных в python https://medium.com/@tyastropheus / tricky- python -ii-передача параметров-для-изменяемых-неизменяемых-объектов-10e968cbda35

0 голосов
/ 01 февраля 2020

Как указывает @Dmitry об неизменяемости и изменчивости, тип списка, в отличие от других типов в python, является изменяемым, то есть операции над списками изменяют сам список, в то время как другие неизменяемые объекты, такие как строки, создают новые экземпляры в памяти. при эксплуатации. Код ниже иллюстрирует это лучше:

lstA = [0, 0, 0]
lstB = lstA
print(lstA is lstB) # True
# change list B
lstB[0] = 9
print(lstA is lstB) # keeps True
strA = "A string"
strB = strA
print(strA is strB) # True
# Change strB
srtB[0] = "B" # Ops! item assignment not supported (immutable object)
# Then let's do it in another way
strB = "B" + strA[1:] # strB = "B string"
print(strA is strN) # False (other string was created)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...