2016-09-18 12 views
0

Я хочу сравнить состояние объекта networkx.Graphn перед вызовом функции d(n) (с побочными эффектами) с состоянием после этого.Как скопировать, но не deepcopy, диаграмму networkx?

Есть атрибуты изменяемого объекта, такие как n.node[0]['attribute'], которые я хочу сравнить.

Очевидно,

before = n 
d() 
after = n 
assert id(before.node[0]['attribute']) == id(after.node[0]['attribute']) 

успешно тривиальным, потому что

before == after 

, но если я устанавливаю before=n.copy(), глубокая копия сделана, и поэтому id(before.node[0]['attribute']) != id(after.node[0]['attribute']). Как получить копию объекта Graph без копирования всех объектов атрибутов узла?

+0

Возможный дубликат [Очистка копии Networkx] (http://stackoverflow.com/questions/29854387/networkx-copy-clarification) – Anaphory

ответ

1

Вызов метода copy дает глубокую копию. Все атрибуты нового графа являются копиями исходного графика. Вызов конструктора (например, Graph(G)) дает мелкую копию, где копируется структура графа, но атрибуты данных являются ссылками на те, которые указаны в исходном графе.

Из copy метода Документов

Всех копий воспроизводят структуру графа, но атрибуты данных могут быть обработаны по-разному. Существует четыре типа копий графа , которые могут потребоваться людям.

Deepcopy - Поведение по умолчанию - это «глубокая копия», где скопированы диаграмма , а также все атрибуты данных и любые объекты, которые они могут содержать . Весь объект графика является новым, поэтому изменения в копия не влияют на исходный объект.

Справочные данные (мелкой) - Для мелкой копии (with_data = False) структура график копируется но край, узел и атрибут графа dicts ссылки на те, в исходном графе. Это экономит время и памяти, но может вызвать путаницу, если вы измените атрибут в одном графике , и он изменит атрибут в другом.

In [1]: import networkx as nx 

In [2]: G = nx.Graph() 

In [3]: G.add_node(1, color=['red']) 

In [4]: G_deep = G.copy() 

In [5]: G_deep.node[1]['color'].append('blue') 

In [6]: list(G.nodes(data=True)) 
Out[6]: [(1, {'color': ['red']})] 

In [7]: list(G_deep.nodes(data=True)) 
Out[7]: [(1, {'color': ['red', 'blue']})] 

In [8]: G_shallow = nx.Graph(G) 

In [9]: G_shallow.node[1]['color'].append('blue') 

In [10]: list(G.nodes(data=True)) 
Out[10]: [(1, {'color': ['red', 'blue']})] 

In [11]: list(G_shallow.nodes(data=True)) 
Out[11]: [(1, {'color': ['red', 'blue']})] 
+0

Это, похоже, больше не соответствует версии 2.0. – xuhdev

-1

Пожалуйста, обратите внимание, что если ваш NetworkX граф содержит объекты объектов ..., даже DeepCopy не будет работать. Это вернет ошибку, что слишком много уровней.

Как правило, я бы подумал, что именно представляет интерес для графика, и просто создайте новый с этим.