Reputation: 6412
I want to compare the state of a networkx.Graph
object n
before a function call d(n)
(with side effects) with the state afterwards.
There are mutable object node attributes such as n.node[0]['attribute']
, which I want to compare.
Obviously,
before = n
d()
after = n
assert id(before.node[0]['attribute']) == id(after.node[0]['attribute'])
succeeds trivially, because
before == after
but if I set before=n.copy()
, a deep copy is made, and therefore id(before.node[0]['attribute']) != id(after.node[0]['attribute'])
. How do I get a copy of a Graph object without copying all node attribute objects?
Upvotes: 2
Views: 8228
Reputation: 30737
Try this:
G = # your graph
G2 = nx.Graph() # or whatever type of graph `G` is
G2.add_edges_from(G.edges())
Upvotes: 1
Reputation: 310
Please also note that if your networkx graph contains objects of objects..., even a deepcopy would not work. It would return an error that there are too many levels.
Normally, I would think what exactly is of interest in the graph and just create a new one with that.
Upvotes: -1
Reputation: 25299
Calling the copy
method gives a deep copy. All attributes of the new graph are copies of the original graph. Calling the constructor (e.g. Graph(G)
) gives a shallow copy where the graph structure is copied but the data attributes are references those in the original graph.
From the copy
method docs
All copies reproduce the graph structure, but data attributes may be handled in different ways. There are four types of copies of a graph that people might want.
Deepcopy -- The default behavior is a "deepcopy" where the graph structure as well as all data attributes and any objects they might contain are copied. The entire graph object is new so that changes in the copy do not affect the original object.
Data Reference (Shallow) -- For a shallow copy (with_data=False) the graph structure is copied but the edge, node and graph attribute dicts are references to those in the original graph. This saves time and memory but could cause confusion if you change an attribute in one graph and it changes the attribute in the other.
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']})]
Upvotes: 5