diff --git a/src/igraph/__init__.py b/src/igraph/__init__.py index 8995047b5..5acec7ba7 100644 --- a/src/igraph/__init__.py +++ b/src/igraph/__init__.py @@ -1919,9 +1919,6 @@ def from_networkx(cls, g): @param g: networkx Graph or DiGraph """ - import networkx as nx - from collections import defaultdict - # Graph attributes gattr = dict(g.graph) @@ -1944,7 +1941,7 @@ def from_networkx(cls, g): # Edges and edge attributes eattr_names = {name for (_, _, data) in g.edges.data() for name in data} - eattr = defaultdict(list) + eattr = {name: [] for name in eattr_names} edges = [] for (u, v, data) in g.edges.data(): edges.append((vd[u], vd[v])) @@ -2037,18 +2034,24 @@ def from_graph_tool(cls, g): graph = cls(n=vcount, directed=g.is_directed(), graph_attrs=gattr) # Node attributes - for key, val in list(g.vertex_properties.items()): + for key, val in g.vertex_properties.items(): prop = val.get_array() for i in range(vcount): graph.vs[i][key] = prop[i] - # Edges - # NOTE: the order the edges are put in is necessary to set the - # attributes later on + # Edges and edge attributes + # NOTE: graph-tool is quite strongly typed, so each property is always + # defined for all edges, using default values for the type. E.g. for a + # string property/attribute the missing edges get an empty string. + edges = [] + eattr_names = list(g.edge_properties) + eattr = {name: [] for name in eattr_names} for e in g.edges(): - edge = graph.add_edge(int(e.source()), int(e.target())) - for key, val in list(g.edge_properties.items()): - edge[key] = val[e] + edges.append((int(e.source()), int(e.target()))) + for name, attr_map in g.edge_properties.items(): + eattr[name].append(attr_map[e]) + + graph.add_edges(edges, eattr) return graph