### Topological sorting example with rustworkx Source: https://www.rustworkx.org/apiref/rustworkx.TopologicalSorter.html This example creates a directed graph, adds nodes and edges, and uses TopologicalSorter to get nodes in topological order. The output shows the nodes returned by get_ready() in each iteration. ```python import rustworkx as rx G = rx.PyDiGraph() G.add_nodes_from(["A", "B", "C", "D", "E", "F"]) G.add_edges_from_no_data([(0, 2),(1, 2), (2, 3), (3, 4), (3, 5)]) sorter = rx.TopologicalSorter(G) while sorter.is_active(): nodes = sorter.get_ready() print(nodes) sorter.done(nodes) ``` ```output [0, 1] [2] [3] [5, 4] ``` -------------------------------- ### Example: Retrieve a mapping with graph_vf2_mapping Source: https://www.rustworkx.org/apiref/rustworkx.graph_vf2_mapping.html Creates two path graphs and uses graph_vf2_mapping with subgraph=True to get an iterator. The example uses next(vf2) inside a try/except to handle StopIteration when no mapping exists. ```python graph_a = rustworkx.generators.path_graph(3) graph_b = rustworkx.generators.path_graph(2) vf2 = rustworkx.graph_vf2_mapping(graph_a, graph_b, subgraph=True) try: mapping = next(vf2) except StopIteration: pass ``` -------------------------------- ### Python example: record tree edges with DFSVisitor Source: https://www.rustworkx.org/apiref/rustworkx.dfs_search.html Example that defines a TreeEdgesRecorder subclass of DFSVisitor to collect tree edges, then runs dfs_search on a PyGraph and prints the recorded edges. ```python import rustworkx as rx from rustworkx.visit import DFSVisitor class TreeEdgesRecorder(DFSVisitor): def __init__(self): self.edges = [] def tree_edge(self, edge): self.edges.append(edge) graph = rx.PyGraph() graph.extend_from_edge_list([(1, 3), (0, 1), (2, 1), (0, 2)]) vis = TreeEdgesRecorder() rx.dfs_search(graph, [0], vis) print('Tree edges:', vis.edges) ``` -------------------------------- ### Example: Using PyDAG.successor_indices Source: https://www.rustworkx.org/apiref/rustworkx.PyDAG.successor_indices.html Shows how to create a PyDiGraph, add nodes, extend with edges, and call successor_indices(1) to get the successors of node 'B'. The output is NodeIndices[4, 3, 2]. ```python >>> G = rx.PyDiGraph() >>> G.add_nodes_from(["A", "B", "C", "D", "E"]) NodeIndices[0, 1, 2, 3, 4] >>> G.extend_from_edge_list([(0, 1), (1, 2), (1, 3), (1, 4)]) >>> G.successor_indices(1) # successors of the 'B' node NodeIndices[4, 3, 2] ``` -------------------------------- ### Example: Using rustworkx.topological_sort Source: https://www.rustworkx.org/apiref/rustworkx.topological_sort.html Creates a PyDiGraph, adds nodes and edges, and calls rx.topological_sort to get a NodeIndices object representing a topological order. The output shows the resulting NodeIndices. ```python >>> G = rx.PyDiGraph() >>> G.add_nodes_from(["A", "B", "C", "D", "E", "F", "G"]) >>> G.add_edges_from_no_data([(0, 1),(1, 2), (2, 3), (3, 4), (5, 2), (6, 3)]) >>> rx.topological_sort(G) NodeIndices[6, 5, 0, 1, 2, 3, 4] ``` -------------------------------- ### Using WeightedEdgeList with indexing and iteration Source: https://www.rustworkx.org/apiref/rustworkx.WeightedEdgeList.html Shows how to create a directed path graph, get its weighted edge list, and access elements via index and iteration. The example uses rustworkx.generators.directed_path_graph and the weighted_edge_list method. ```python import rustworkx as rx graph = rx.generators.directed_path_graph(5) edges = graph.weighted_edge_list() # Index based access third_element = edges[2] # Use as iterator edges_iter = iter(edges) first_element = next(edges_iter) second_element = next(edges_iter) ``` -------------------------------- ### Example: Track tree edges with DFSVisitor Source: https://www.rustworkx.org/apiref/rustworkx.digraph_dfs_search.html Python example that defines a TreeEdgesRecorder subclass of DFSVisitor to collect tree edges during a depth-first search. It creates a PyDiGraph, runs digraph_dfs_search with source [0], and prints the recorded edges. ```python import rustworkx as rx from rustworkx.visit import DFSVisitor class TreeEdgesRecorder(DFSVisitor): def __init__(self): self.edges = [] def tree_edge(self, edge): self.edges.append(edge) graph = rx.PyDiGraph() graph.extend_from_edge_list([(1, 3), (0, 1), (2, 1), (0, 2)]) vis = TreeEdgesRecorder() rx.digraph_dfs_search(graph, [0], vis) print('Tree edges:', vis.edges) ``` ```output Tree edges: [(0, 2, None), (2, 1, None), (1, 3, None)] ``` -------------------------------- ### Example: Draw a directed path graph with mpl_draw Source: https://www.rustworkx.org/apiref/rustworkx.visualization.mpl_draw.html This example imports matplotlib.pyplot, rustworkx, and the mpl_draw function, creates a directed path graph with 25 nodes, and draws it using mpl_draw, followed by plt.draw() to render the plot. ```python import matplotlib.pyplot as plt import rustworkx as rx from rustworkx.visualization import mpl_draw G = rx.generators.directed_path_graph(25) mpl_draw(G) plt.draw() ``` -------------------------------- ### Chain decomposition example with mpl_draw Source: https://www.rustworkx.org/release_notes.html Creates a PyGraph, computes its chain decomposition, and colors edges by chain using mpl_draw. The example defines a color_edges function that assigns blue and red to edges in chains and black to others. ```python import rustworkx from rustworkx.visualization import mpl_draw graph = rustworkx.PyGraph() graph.extend_from_edge_list([ (0, 1), (0, 2), (1, 2), (2, 3), (3, 4), (3, 5), (4, 5), ]) chains = rustworkx.chain_decomposition(graph) def color_edges(graph, chains): COLORS = ['blue', 'red'] edges_in_chain = {} for idx, chain in enumerate(chains): for edge in chain: edge = tuple(sorted(edge)) edges_in_chain[edge] = COLORS[idx] edge_colors = [] for edge in graph.edge_list(): edge = tuple(sorted(edge)) edge_colors += [edges_in_chain.get(edge, 'black')] return edge_colors mpl_draw(graph, node_color='black', node_size=150, edge_color=color_edges(graph, chains)) ``` -------------------------------- ### Example: Using PyDAG.neighbors to get successors Source: https://www.rustworkx.org/apiref/rustworkx.PyDAG.neighbors.html This example creates a PyDiGraph, adds nodes and edges, and calls neighbors(1) to get the successor indices of node 'B'. The output shows NodeIndices[4, 3, 2]. ```python >>> G = rx.PyDiGraph() >>> G.add_nodes_from(["A", "B", "C", "D", "E"]) NodeIndices[0, 1, 2, 3, 4] >>> G.extend_from_edge_list([(0, 1), (1, 2), (1, 3), (1, 4)]) >>> G.neighbors(1) # neighbors of the 'B' node NodeIndices[4, 3, 2] ``` -------------------------------- ### Example: Accessing AllPairsPathLengthMapping Source: https://www.rustworkx.org/apiref/rustworkx.AllPairsPathLengthMapping.html Shows how to create a graph, compute all-pairs shortest path lengths, and access the result for a specific node index. ```python import rustworkx as rx graph = rx.generators.directed_path_graph(5) edges = rx.all_pairs_dijkstra_shortest_path_lengths(graph) # Target node access third_node_shortest_path_lengths = edges[2] ``` -------------------------------- ### Example of using graph_cartesian_product Source: https://www.rustworkx.org/apiref/rustworkx.graph_cartesian_product.html Demonstrates how to create two path graphs and compute their cartesian product, then draw the resulting graph using mpl_draw. ```python import rustworkx.generators from rustworkx.visualization import mpl_draw graph_1 = rustworkx.generators.path_graph(2) graph_2 = rustworkx.generators.path_graph(3) graph_product, _ = rustworkx.graph_cartesian_product(graph_1, graph_2) mpl_draw(graph_product) ``` -------------------------------- ### Build first graph and visualize Source: https://www.rustworkx.org/apiref/rustworkx.PyGraph.compose.html Creates a PyGraph with three nodes and two edges, then visualizes it using mpl_draw. This is the first step in the compose example. ```python import os import tempfile import pydot from PIL import Image import rustworkx as rx from rustworkx.visualization import mpl_draw # Build first graph and visualize: graph = rx.PyGraph() node_a, node_b, node_c = graph.add_nodes_from(['A', 'B', 'C']) graph.add_edges_from([(node_a, node_b, 'A to B'), (node_b, node_c, 'B to C')]) mpl_draw(graph, with_labels=True, labels=str, edge_labels=str) ``` -------------------------------- ### Example of using graph_tensor_product Source: https://www.rustworkx.org/apiref/rustworkx.graph_tensor_product.html Demonstrates creating two path graphs and computing their tensor product, then drawing the result with mpl_draw. ```python import rustworkx.generators from rustworkx.visualization import mpl_draw graph_1 = rustworkx.generators.path_graph(2) graph_2 = rustworkx.generators.path_graph(3) graph_product, _ = rustworkx.graph_tensor_product(graph_1, graph_2) mpl_draw(graph_product) ``` -------------------------------- ### Get neighbors of a node with PyDAG.adj Source: https://www.rustworkx.org/apiref/rustworkx.PyDAG.adj.html Shows how to use PyDAG.adj to retrieve the neighbors of a node. The example creates a PyDiGraph, adds nodes and weighted edges, then calls adj(2) to get neighbors of node 'C'. The output is a dictionary with node indices as keys and edge data as values. ```python >>> G = rx.PyDiGraph() >>> G.add_nodes_from(["A", "B", "C", "D", "E"]) >>> NodeIndices[0, 1, 2, 3, 4] >>> G.extend_from_weighted_edge_list([(0, 2, "A->C"), (1, 2, "B->C"), (2, 3, "C->D"), (3, 4, "D->E")]) >>> G.adj(2) # neighbors of the node "C" {1: 'B->C', 0: 'A->C', 3: 'C->D'} ``` -------------------------------- ### Example usage of topological_generations Source: https://www.rustworkx.org/apiref/rustworkx.topological_generations.html Constructs a PyDiGraph with nodes 0-4 and edges forming a DAG, then calls topological_generations to get generations. The output shows each generation as a NodeIndices list. ```python >>> G = rx.PyDiGraph() >>> G.add_nodes_from([0, 1, 2, 3, 4]) >>> G.add_edges_from_no_data([(0, 1), (0, 2), (1, 3), (2, 3), (3, 4)]) >>> rx.topological_generations(G) [NodeIndices[0], NodeIndices[1, 2], NodeIndices[3], NodeIndices[4]] ``` -------------------------------- ### Example of using digraph_tensor_product Source: https://www.rustworkx.org/apiref/rustworkx.digraph_tensor_product.html Demonstrates creating two directed path graphs and computing their tensor product, then drawing the result with mpl_draw. ```python import rustworkx.generators from rustworkx.visualization import mpl_draw graph_1 = rustworkx.generators.directed_path_graph(2) graph_2 = rustworkx.generators.directed_path_graph(3) graph_product, _ = rustworkx.digraph_tensor_product(graph_1, graph_2) mpl_draw(graph_product) ``` -------------------------------- ### Build first graph and visualize Source: https://www.rustworkx.org/apiref/rustworkx.PyDAG.compose.html Creates a PyDiGraph with nodes A, B, C and edges between them, then visualizes it with mpl_draw. ```python import rustworkx as rx from rustworkx.visualization import mpl_draw # Build first graph and visualize: graph = rx.PyDiGraph() node_a = graph.add_node('A') node_b = graph.add_child(node_a, 'B', 'A to B') node_c = graph.add_child(node_b, 'C', 'B to C') mpl_draw(graph, with_labels=True, labels=str, edge_labels=str) ``` -------------------------------- ### Example return dictionary of path lengths Source: https://www.rustworkx.org/apiref/rustworkx.digraph_floyd_warshall.html Shows the format of the returned dictionary, mapping source node indices to dictionaries of target nodes and shortest path lengths. ```python { 0: {0: 0.0, 1: 2.0, 2: 2.0}, 1: {1: 0.0, 2: 1.0}, 2: {0: 1.0, 2: 0.0}, } ``` -------------------------------- ### Count weakly connected components in a directed graph Source: https://www.rustworkx.org/apiref/rustworkx.number_weakly_connected_components.html Creates a PyDiGraph, extends it with an edge list, and calls number_weakly_connected_components to get the count. The example returns 2 for the given graph. ```python >>> G = rx.PyDiGraph() >>> G.extend_from_edge_list([(0, 1), (1, 2), (3, 4)]) >>> rx.number_weakly_connected_components(G) 2 ``` -------------------------------- ### Python example: find shortest path from vertex 0 to 5 using dijkstra_search Source: https://www.rustworkx.org/apiref/rustworkx.dijkstra_search.html Example that creates a directed graph, defines a DijkstraVisitor subclass to record predecessors and stop when the goal vertex is discovered, then calls rx.dijkstra_search with source [0] and weight_fn=None. The printed output is 'Path: [0, 4, 5]'. ```python import rustworkx as rx from rustworkx.visit import DijkstraVisitor, StopSearch graph = rx.PyDiGraph() graph.extend_from_edge_list([ (0, 1), (0, 2), (0, 3), (0, 4), (1, 3), (2, 3), (2, 4), (4, 5), ]) class PathFinder(DijkstraVisitor): def __init__(self, start, goal): self.start = start self.goal = goal self.predecessors = {} def get_path(self): n = self.goal rev_path = [n] while n != self.start: n = self.predecessors[n] rev_path.append(n) return list(reversed(rev_path)) def discover_vertex(self, vertex, cost): if vertex == self.goal: raise StopSearch def edge_relaxed(self, edge): self.predecessors[edge[1]] = edge[0] start = 0 vis = PathFinder(start=start, goal=5) rx.dijkstra_search(graph, [start], weight_fn=None, visitor=vis) print('Path:', vis.get_path()) ``` ```text Path: [0, 4, 5] ``` -------------------------------- ### Example usage of PyDAG.predecessor_indices Source: https://www.rustworkx.org/apiref/rustworkx.PyDAG.predecessor_indices.html Creates a PyDiGraph, adds nodes and edges, then calls predecessor_indices(3) to get the predecessors of node 'D'. The output shows NodeIndices[2, 1, 0]. ```python >>> G = rx.PyDiGraph() >>> G.add_nodes_from(["A", "B", "C", "D", "E"]) NodeIndices[0, 1, 2, 3, 4] >>> G.extend_from_edge_list([(0, 3), (1, 3), (2, 3), (3, 4)]) >>> G.predecessor_indices(3) # predecessors of the 'D' node NodeIndices[2, 1, 0] ``` -------------------------------- ### Retrieve a mapping with digraph_vf2_mapping Source: https://www.rustworkx.org/apiref/rustworkx.digraph_vf2_mapping.html Creates two directed path graphs and uses digraph_vf2_mapping with subgraph=True to get an iterator. The example then attempts to retrieve the first mapping, catching StopIteration if no mapping exists. ```python graph_a = rustworkx.generators.directed_path_graph(3) graph_b = rustworkx.generators.direccted_path_graph(2) vf2 = rustworkx.digraph_vf2_mapping(graph_a, graph_b, subgraph=True) try: mapping = next(vf2) except StopIteration: pass ``` -------------------------------- ### Using IndexPartitionBlock with digraph_maximum_bisimulation Source: https://www.rustworkx.org/apiref/rustworkx.IndexPartitionBlock.html Shows how to access elements of an IndexPartitionBlock by index and iterate over it. The example creates a directed path graph with two nodes, computes the maximum bisimulation partition, and demonstrates both index-based access and iteration. ```python import rustworkx as rx graph = rx.generators.directed_path_graph(2) partition = rx.digraph_maximum_bisimulation(graph) a_partition_block = partition[0] # Index based access first_element = a_partition_block[0] # Use as iterator block_iter = iter(a_partition_block) another_element = next(block_iter) the_second_element = next(block_iter) ``` -------------------------------- ### Example: Using lexicographical_topological_sort with a key Source: https://www.rustworkx.org/apiref/rustworkx.lexicographical_topological_sort.html Creates a PyDiGraph with nodes labeled A through G, adds edges from each of A-F to G, then shows that topological_sort returns nodes in arbitrary order while lexicographical_topological_sort with key=str returns them in alphabetical order. ```python >>> G = rx.PyDiGraph() >>> a, b, c, d, e, f, g = G.add_nodes_from(["A", "B", "C", "D", "E", "F", "G"]) >>> G.add_edges_from_no_data([(a, g), (b, g), (c, g), (d, g), (e, g), (f, g)]) >>> rx.topological_sort(G) NodeIndices[5, 4, 3, 2, 1, 0, 6] # First 6 items in any order >>> rx.lexicographical_topological_sort(G, key=str) ['A', 'B', 'C', 'D', 'E', 'F', 'G'] # First 6 items in alphabetical order ``` -------------------------------- ### Record tree edges with BFSVisitor Source: https://www.rustworkx.org/_modules/rustworkx.html Example of using rustworkx.bfs_search with a custom BFSVisitor subclass to record tree edges during traversal. The visitor's tree_edge method appends each edge to a list. The graph is a PyDiGraph and the search starts from node 0. ```python import rustworkx as rx from rustworkx.visit import BFSVisitor class TreeEdgesRecorder(BFSVisitor): def __init__(self): self.edges = [] def tree_edge(self, edge): self.edges.append(edge) graph = rx.PyDiGraph() graph.extend_from_edge_list([(1, 3), (0, 1), (2, 1), (0, 2)]) vis = TreeEdgesRecorder() rx.bfs_search(graph, [0], vis) print('Tree edges:', vis.edges) ``` -------------------------------- ### Install cargo-fuzz Source: https://www.rustworkx.org/CONTRIBUTING.html Installs the cargo-fuzz tool required for fuzz testing. ```bash cargo install cargo-fuzz ``` -------------------------------- ### Using PathMapping with dijkstra_shortest_paths Source: https://www.rustworkx.org/apiref/rustworkx.PathMapping.html Shows how to access a path by target node index and iterate over the mapping. The example creates a directed path graph of 5 nodes and computes shortest paths from node 0. ```python import rustworkx as rx graph = rx.generators.directed_path_graph(5) edges = rx.dijkstra_shortest_paths(0) # Target node access third_element = edges[2] # Use as iterator edges_iter = iter(edges) first_target = next(edges_iter) first_path = edges[first_target] second_target = next(edges_iter) second_path = edges[second_target] ``` -------------------------------- ### Basic mpl_draw visualization Source: https://www.rustworkx.org/release_notes.html Visualizes a grid graph without labels using rustworkx.visualization.mpl_draw. Requires matplotlib, installable via pip install matplotlib or pip install 'rustworkx[mpl]'. ```python import rustworkx from rustworkx.visualization import mpl_draw graph = rustworkx.generators.grid_graph(4, 6) mpl_draw(graph) ``` -------------------------------- ### Example of using digraph_cartesian_product Source: https://www.rustworkx.org/apiref/rustworkx.digraph_cartesian_product.html Creates two directed path graphs, computes their cartesian product, and draws the result using mpl_draw. ```python import rustworkx.generators from rustworkx.visualization import mpl_draw graph_1 = rustworkx.generators.directed_path_graph(2) graph_2 = rustworkx.generators.directed_path_graph(3) graph_product, _ = rustworkx.digraph_cartesian_product(graph_1, graph_2) mpl_draw(graph_product) ``` -------------------------------- ### draw_nodes function body: imports, axis setup, and scatter Source: https://www.rustworkx.org/_modules/rustworkx/visualization/matplotlib.html This snippet contains the implementation body of the draw_nodes function. It imports matplotlib modules, raises an ImportError if matplotlib is not installed, sets up the axes, filters the node list, handles empty node lists, converts positions to a numpy array, applies alpha to node colors, and calls ax.scatter to draw the nodes. It also disables axis ticks. ```python try: import matplotlib as mpl import matplotlib.collections # type: ignore import matplotlib.pyplot as plt except ImportError as e: raise ImportError( "matplotlib needs to be installed prior to running " "rustworkx.visualization.mpl_draw(). You can install " "matplotlib with:\n'pip install matplotlib'" ) from e if ax is None: ax = plt.gca() if node_list is None: node_list = graph.node_indices() # empty node_list, no drawing if len(node_list) == 0: return mpl.collections.PathCollection(None) try: xy = np.asarray([pos[v] for v in node_list]) except KeyError as e: raise IndexError(f"Node {e} has no position.") from e if isinstance(alpha, Iterable): node_color = apply_alpha(node_color, alpha, node_list, cmap, vmin, vmax) alpha = None node_collection = ax.scatter( xy[:, 0], xy[:, 1], s=node_size, c=node_color, marker=node_shape, cmap=cmap, vmin=vmin, vmax=vmax, alpha=alpha, linewidths=linewidths, edgecolors=edgecolors, label=label, ) ax.tick_params( axis="both", which="both", bottom=False, left=False, labelbottom=False, labelleft=False, ) ``` -------------------------------- ### Build second graph and visualize Source: https://www.rustworkx.org/apiref/rustworkx.PyGraph.compose.html Creates a second PyGraph with two nodes and one edge, then visualizes it. This is the second step in the compose example. ```python # Build second graph and visualize: other_graph = rx.PyGraph() node_d, node_e = other_graph.add_nodes_from(['D', 'E']) other_graph.add_edge(node_d, node_e, 'D to E') mpl_draw(other_graph, with_labels=True, labels=str, edge_labels=str) ``` -------------------------------- ### Customized mpl_draw visualization Source: https://www.rustworkx.org/release_notes.html Visualizes a grid graph with custom node and edge colors using mpl_draw. Requires matplotlib, installable via pip install matplotlib or pip install 'rustworkx[mpl]'. ```python import rustworkx from rustworkx.visualization import mpl_draw graph = rustworkx.generators.grid_graph(4, 6) mpl_draw(graph, node_color='r', edge_color='#00FFFF') ``` -------------------------------- ### Example usage of PathLengthMapping with dijkstra_shortest_path_lengths Source: https://www.rustworkx.org/apiref/rustworkx.PathLengthMapping.html Shows how to access target nodes by index and iterate over the mapping. The example creates a directed path graph with 5 nodes and computes shortest path lengths from node 0. It demonstrates direct access via edges[2] and iteration using iter(edges). ```python import rustworkx as rx graph = rx.generators.directed_path_graph(5) edges = rx.dijkstra_shortest_path_lengths(0) # Target node access third_element = edges[2] # Use as iterator edges_iter = iter(edges) first_target = next(edges_iter) first_path = edges[first_target] second_target = next(edges_iter) second_path = edges[second_target] ``` -------------------------------- ### Install reno with pip Source: https://www.rustworkx.org/CONTRIBUTING.html Install the reno tool using pip. Required before creating release notes. ```bash pip install -U reno ``` -------------------------------- ### Construct a line graph with graph_line_graph() Source: https://www.rustworkx.org/release_notes.html Creates a PyGraph, adds nodes and edges, then calls rx.graph_line_graph() to build the line graph. The example asserts the resulting node indices, edge list, and edge map, then draws the graph with mpl_draw. ```python import rustworkx as rx from rustworkx.visualization import mpl_draw graph = rx.PyGraph() node_a = graph.add_node("a") node_b = graph.add_node("b") node_c = graph.add_node("c") node_d = graph.add_node("d") edge_ab = graph.add_edge(node_a, node_b, 1) edge_ac = graph.add_edge(node_a, node_c, 1) edge_bc = graph.add_edge(node_b, node_c, 1) edge_ad = graph.add_edge(node_a, node_d, 1) out_graph, out_edge_map = rx.graph_line_graph(graph) assert out_graph.node_indices() == [0, 1, 2, 3] assert out_graph.edge_list() == [(3, 1), (3, 0), (1, 0), (2, 0), (2, 1)] assert out_edge_map == {edge_ab: 0, edge_ac: 1, edge_bc: 2, edge_ad: 3} mpl_draw(out_graph, with_labels=True) ``` -------------------------------- ### Output of tree edges example Source: https://www.rustworkx.org/apiref/rustworkx.dfs_search.html The output produced by the preceding Python example, showing the recorded tree edges. ```text Tree edges: [(0, 2, None), (2, 1, None), (1, 3, None)] ``` -------------------------------- ### Initialize Graph from Edge List: NetworkX vs rustworkx Source: https://www.rustworkx.org/networkx.html Shows how to create a graph from an edge list in both NetworkX and rustworkx. rustworkx requires a list of 2-tuples, while NetworkX can accept an iterator. ```python Graph([(0, 1), (1, 0)]) ``` ```python graph = PyGraph() graph.extend_from_edge_list([(0, 1), (1, 0)]) ```