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

Ana*_*ory 2 deep-copy networkx

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

有可变对象节点属性n.node[0]['attribute'],例如我想比较的。

明显地,

before = n
d()
after = n
assert id(before.node[0]['attribute']) == id(after.node[0]['attribute'])
Run Code Online (Sandbox Code Playgroud)

取得了微不足道的成功,因为

before == after
Run Code Online (Sandbox Code Playgroud)

但如果我设置before=n.copy(),则会进行深层复制,因此id(before.node[0]['attribute']) != id(after.node[0]['attribute']). 如何在不复制所有节点属性对象的情况下获取 Graph 对象的副本?

Ari*_*ric 5

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

来自copy方法文档

所有副本都会重现图结构,但数据属性可以以不同的方式处理。人们可能需要四种类型的图表副本。

Deepcopy——默认行为是“deepcopy”,其中复制图形结构以及所有数据属性和它们可能包含的任何对象。整个图形对象是新的,因此副本中的更改不会影响原始对象。

数据引用(浅)——对于浅复制(with_data=False),图结构被复制,但边、节点和图属性字典是对原始图中的引用。这可以节省时间和内存,但如果您更改一个图中的属性而更改另一个图中的属性,则可能会导致混乱。

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']})]
Run Code Online (Sandbox Code Playgroud)

  • 从 2.0 版本开始,这似乎不再成立。 (6认同)