def contracted_nodes(G, u, v, self_loops=True):
 H = G.copy()
 if H.is_directed():
  in_edges = ((w, u, d) for (w, x, d) in G.in_edges(v, data=True) if (self_loops or (w != u)))
  out_edges = ((u, w, d) for (x, w, d) in G.out_edges(v, data=True) if (self_loops or (w != u)))
  new_edges = chain(in_edges, out_edges)
 else:
  new_edges = ((u, w, d) for (x, w, d) in G.edges(v, data=True) if (self_loops or (w != u)))
 v_data = H.node[v]
 H.remove_node(v)
 H.add_edges_from(new_edges)
 if ('contraction' in H.node[u]):
  H.node[u]['contraction'][v] = v_data
 else:
  H.node[u]['contraction'] = {v: v_data}
 return H

def contracted_nodes ( G , u , v , self_loops = True ) : H = G . copy ( ) if H . is_directed ( ) : in_edges = ( ( w , u , d ) for ( w , x , d ) in G . in_edges ( v , data = True ) if ( self_loops or ( w != u ) ) ) out_edges = ( ( u , w , d ) for ( x , w , d ) in G . out_edges ( v , data = True ) if ( self_loops or ( w != u ) ) ) new_edges = chain ( in_edges , out_edges ) else : new_edges = ( ( u , w , d ) for ( x , w , d ) in G . edges ( v , data = True ) if ( self_loops or ( w != u ) ) ) v_data = H . node [ v ] H . remove_node ( v ) H . add_edges_from ( new_edges ) if ( 'contraction' in H . node [ u ] ) : H . node [ u ] [ 'contraction' ] [ v ] = v_data else : H . node [ u ] [ 'contraction' ] = { v : v_data } return H
returns the graph that results from contracting u and v .