如何复制而不是深度复制 networkx Graph?

How do I copy, but not deepcopy, a networkx Graph?

我想比较 networkx.Graph 对象 n 在函数调用 d(n)(有副作用)之前的状态与之后的状态。

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 对象的副本?

调用copy方法给出深拷贝。新图的所有属性都是原始图的副本。调用构造函数(例如 Graph(G))给出一个浅拷贝,其中复制了图形结构,但数据属性是原始图形中的引用。

来自copy方法文档

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']})]

另请注意,如果您的 networkx 图包含对象的对象...,即使是深度复制也无法正常工作。关卡太多会return报错。

通常情况下,我会考虑图表中到底有什么有趣的地方,然后用它创建一个新的图表。

试试这个:

G = # your graph
G2 = nx.Graph() # or whatever type of graph `G` is
G2.add_edges_from(G.edges())