Views avoid copying big graphs, but misunderstanding them causes surprising bugs when the original changes.
G.nodes, G.edges, G.adj and G.degree are views: read-only, live windows onto the graph's internal dicts. They cost nothing to create and always reflect the current graph, so changing G after creating a view changes what the view shows.
Subgraph views work the same way:
G.subgraph(nodes): the induced subgraph on those nodes.G.edge_subgraph(edges): only the given edges and their endpoints.G.reverse(copy=False)for DiGraphs, andnx.subgraph_view(G, filter_node=f, filter_edge=g)for predicate-based filtering.
These views are frozen: you can't add or remove nodes through them, and they reflect later changes to G. Call .copy() to get an independent, editable graph, for example G.subgraph(nodes).copy(). Note that copy() is shallow for attribute values; a mutable value such as a list stored in an attribute is shared. Use copy.deepcopy if you will mutate those.
Don't remove nodes from G while iterating over G.nodes or a view; it raises RuntimeError: dictionary changed size during iteration. Collect them first: G.remove_nodes_from([n for n in G if cond(n)]).
nx.relabel_nodes(G, mapping) renames nodes, returning a copy by default; nx.freeze(G) makes a graph immutable.
Example
import networkx as nx
G = nx.path_graph(6) # 0-1-2-3-4-5
sub = G.subgraph([1, 2, 3]) # a view, no copy
print(sorted(sub.edges)) # [(1, 2), (2, 3)]
G.remove_edge(2, 3) # change the original...
print(sorted(sub.edges)) # [(1, 2)] ...and the view follows
try:
sub.add_edge(1, 3)
except nx.NetworkXError as e:
print(e) # Frozen graph can't be modified
own = G.subgraph([1, 2, 3]).copy() # independent and editable
own.add_edge(1, 3)
print(G.has_edge(1, 3)) # False
G.remove_nodes_from([n for n in G if G.degree(n) == 0]) # safe bulk removal
big = nx.subgraph_view(G, filter_node=lambda n: n >= 3)
print(sorted(big.nodes)) # [3, 4, 5]Remember
G.nodes,G.edges,G.adjand subgraphs are live, read-only views- Call
.copy()for an independent, editable subgraph - Don't mutate a graph while iterating over its views
Watch out for
- Keeping a subgraph view, then editing the original graph and being surprised the 'snapshot' changed.