Я пытаюсь создать совокупность матриц смежности с разными случайными весами, для которых я использую приведенный ниже код. Однако моя проблема заключается в том, что после запуска все веса соответствуют последней итерации понимания списка? При печати этих adjacencylists
во время генерации все работает нормально, однако вывод функции getPopulation
в 5 раз превышает тот же набор параметров.
Кажется, что это было бы легко исправить, но чего-то (я думаю, возможно, очень простого) не хватает. Может быть, проблема, когда требуется глубокая копия или что-то в этом роде?
Уже пробовал использовать обычные циклы for, операторы печати и т.д.
import networkx as nx
import numpy as np
G = nx.DiGraph()
G.add_nodes_from(["Sadness", "Avoidance", "Guilt"])
G.add_edges_from([("Sadness", "Avoidance")], weight=1)
G.add_edges_from([("Avoidance", "Sadness")], weight=1)
G.add_edges_from([("Avoidance", "Guilt"), ("Guilt", "Sadness")], weight=1)
parameters = nx.to_numpy_matrix(G)
def getRandParamValue(adj):
for p in np.transpose(adj.nonzero()):
adj[p[0], p[1]] = adj[p[0], p[1]] * np.random.uniform()
print(adj)
return adj
def getPopulation(size, initParam):
return [getRandParamValue(initParam) for i in range(size)]
getPopulation(5, parameters)
После печати вывода в функции getRandParamValue все работает нормально:
[[0. 0.40218464 0. ]
[0.07330473 0. 0.7196376 ]
[0.53148413 0. 0. ]]
[[0. 0.34256617 0. ]
[0.01773899 0. 0.12460768]
[0.1401687 0. 0. ]]
[[0. 0.11086942 0. ]
[0.01449088 0. 0.04592752]
[0.07903259 0. 0. ]]
[[0. 0.01970867 0. ]
[0.00589168 0. 0.00860802]
[0.06942081 0. 0. ]]
[[0. 0.01045412 0. ]
[0.00084878 0. 0.00713334]
[0.0024654 0. 0. ]]
Однако вывод getPopulation
не идентичен предыдущему выводу, хотя этого и следовало ожидать:
[matrix([[0. , 0.01045412, 0. ],
[0.00084878, 0. , 0.00713334],
[0.0024654 , 0. , 0. ]]),
matrix([[0. , 0.01045412, 0. ],
[0.00084878, 0. , 0.00713334],
[0.0024654 , 0. , 0. ]]),
matrix([[0. , 0.01045412, 0. ],
[0.00084878, 0. , 0.00713334],
[0.0024654 , 0. , 0. ]]),
matrix([[0. , 0.01045412, 0. ],
[0.00084878, 0. , 0.00713334],
[0.0024654 , 0. , 0. ]]),
matrix([[0. , 0.01045412, 0. ],
[0.00084878, 0. , 0.00713334],
[0.0024654 , 0. , 0. ]])]
Матрица параметров выглядит следующим образом:
[[0. 1. 0.]
[1. 0. 1.]
[1. 0. 0.]]
Потрясающий! Спасибо большое, а зачем это нужно?
Возможный дубликат Как клонировать или скопировать список?
@BasChatel это потому, что массивы numpy являются изменяемыми, не уверен, что могу дать больше объяснений, возможно, прочитайте это (не в stackoverflow), это может помочь вам лучше понять.
Я хочу добавить комментарий к тому, что вы делаете, если вы определяете size
большим числом, все значение будет стремиться к 0, так как каждый раз, когда вы умножаете предыдущее значение на значение от 0 до 1, посмотрите сами с печатью последний элемент списка из 100 элементов: print (getPopulation(100, parameters)[-1])
. Просто чтобы быть уверенным, что вы сейчас, что произойдет
Итак, проблема в следующем:
def myfunction(L):
L[0] += 1
return L
my_outer_list = [1,2,3]
newlist = myfunction(my_outer_list)
print(newlist)
> [2, 2, 3]
print(my_outer_list)
> [2, 2, 3]
newlist[2]=-1
print(newlist)
> [2, 2, -1]
print(my_outer_list)
> [2, 2, -1]
Я передал объект my_outer_list
в функцию. Затем этот объект модифицируется, и объект возвращается. Так что теперь newlist
и my_outer_list
не просто равны, это два разных названия одного и того же. То, что я делаю с этим объектом, изменяет объект, и вы видите эти изменения независимо от того, какое имя вы используете.
Вот что случилось с тобой. Если бы вместо этого у меня было myfunction
return L.copy()
, он вернул бы копию L
, а не точно L
.
Так что вам стоит вернуться adj.copy()
.
Спасибо за ваше объяснение! Вы все мне очень помогли :)
если вы хотите, чтобы в вашем списке был тот же результат, что и напечатанный, просто добавьте
.copy()
вreturn
изgetRandParamValue
, напримерreturn adj.copy()