Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.9/dist-packages/networkx/readwrite/adjlist.py: 19%
57 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-10-20 07:00 +0000
« prev ^ index » next coverage.py v7.3.2, created at 2023-10-20 07:00 +0000
1"""
2**************
3Adjacency List
4**************
5Read and write NetworkX graphs as adjacency lists.
7Adjacency list format is useful for graphs without data associated
8with nodes or edges and for nodes that can be meaningfully represented
9as strings.
11Format
12------
13The adjacency list format consists of lines with node labels. The
14first label in a line is the source node. Further labels in the line
15are considered target nodes and are added to the graph along with an edge
16between the source node and target node.
18The graph with edges a-b, a-c, d-e can be represented as the following
19adjacency list (anything following the # in a line is a comment)::
21 a b c # source target target
22 d e
23"""
25__all__ = ["generate_adjlist", "write_adjlist", "parse_adjlist", "read_adjlist"]
27import networkx as nx
28from networkx.utils import open_file
31def generate_adjlist(G, delimiter=" "):
32 """Generate a single line of the graph G in adjacency list format.
34 Parameters
35 ----------
36 G : NetworkX graph
38 delimiter : string, optional
39 Separator for node labels
41 Returns
42 -------
43 lines : string
44 Lines of data in adjlist format.
46 Examples
47 --------
48 >>> G = nx.lollipop_graph(4, 3)
49 >>> for line in nx.generate_adjlist(G):
50 ... print(line)
51 0 1 2 3
52 1 2 3
53 2 3
54 3 4
55 4 5
56 5 6
57 6
59 See Also
60 --------
61 write_adjlist, read_adjlist
63 Notes
64 -----
65 The default `delimiter=" "` will result in unexpected results if node names contain
66 whitespace characters. To avoid this problem, specify an alternate delimiter when spaces are
67 valid in node names.
69 NB: This option is not available for data that isn't user-generated.
71 """
72 directed = G.is_directed()
73 seen = set()
74 for s, nbrs in G.adjacency():
75 line = str(s) + delimiter
76 for t, data in nbrs.items():
77 if not directed and t in seen:
78 continue
79 if G.is_multigraph():
80 for d in data.values():
81 line += str(t) + delimiter
82 else:
83 line += str(t) + delimiter
84 if not directed:
85 seen.add(s)
86 yield line[: -len(delimiter)]
89@open_file(1, mode="wb")
90def write_adjlist(G, path, comments="#", delimiter=" ", encoding="utf-8"):
91 """Write graph G in single-line adjacency-list format to path.
94 Parameters
95 ----------
96 G : NetworkX graph
98 path : string or file
99 Filename or file handle for data output.
100 Filenames ending in .gz or .bz2 will be compressed.
102 comments : string, optional
103 Marker for comment lines
105 delimiter : string, optional
106 Separator for node labels
108 encoding : string, optional
109 Text encoding.
111 Examples
112 --------
113 >>> G = nx.path_graph(4)
114 >>> nx.write_adjlist(G, "test.adjlist")
116 The path can be a filehandle or a string with the name of the file. If a
117 filehandle is provided, it has to be opened in 'wb' mode.
119 >>> fh = open("test.adjlist", "wb")
120 >>> nx.write_adjlist(G, fh)
122 Notes
123 -----
124 The default `delimiter=" "` will result in unexpected results if node names contain
125 whitespace characters. To avoid this problem, specify an alternate delimiter when spaces are
126 valid in node names.
127 NB: This option is not available for data that isn't user-generated.
129 This format does not store graph, node, or edge data.
131 See Also
132 --------
133 read_adjlist, generate_adjlist
134 """
135 import sys
136 import time
138 pargs = comments + " ".join(sys.argv) + "\n"
139 header = (
140 pargs
141 + comments
142 + f" GMT {time.asctime(time.gmtime())}\n"
143 + comments
144 + f" {G.name}\n"
145 )
146 path.write(header.encode(encoding))
148 for line in generate_adjlist(G, delimiter):
149 line += "\n"
150 path.write(line.encode(encoding))
153@nx._dispatch(graphs=None)
154def parse_adjlist(
155 lines, comments="#", delimiter=None, create_using=None, nodetype=None
156):
157 """Parse lines of a graph adjacency list representation.
159 Parameters
160 ----------
161 lines : list or iterator of strings
162 Input data in adjlist format
164 create_using : NetworkX graph constructor, optional (default=nx.Graph)
165 Graph type to create. If graph instance, then cleared before populated.
167 nodetype : Python type, optional
168 Convert nodes to this type.
170 comments : string, optional
171 Marker for comment lines
173 delimiter : string, optional
174 Separator for node labels. The default is whitespace.
176 Returns
177 -------
178 G: NetworkX graph
179 The graph corresponding to the lines in adjacency list format.
181 Examples
182 --------
183 >>> lines = ["1 2 5", "2 3 4", "3 5", "4", "5"]
184 >>> G = nx.parse_adjlist(lines, nodetype=int)
185 >>> nodes = [1, 2, 3, 4, 5]
186 >>> all(node in G for node in nodes)
187 True
188 >>> edges = [(1, 2), (1, 5), (2, 3), (2, 4), (3, 5)]
189 >>> all((u, v) in G.edges() or (v, u) in G.edges() for (u, v) in edges)
190 True
192 See Also
193 --------
194 read_adjlist
196 """
197 G = nx.empty_graph(0, create_using)
198 for line in lines:
199 p = line.find(comments)
200 if p >= 0:
201 line = line[:p]
202 if not len(line):
203 continue
204 vlist = line.strip().split(delimiter)
205 u = vlist.pop(0)
206 # convert types
207 if nodetype is not None:
208 try:
209 u = nodetype(u)
210 except BaseException as err:
211 raise TypeError(
212 f"Failed to convert node ({u}) to type " f"{nodetype}"
213 ) from err
214 G.add_node(u)
215 if nodetype is not None:
216 try:
217 vlist = list(map(nodetype, vlist))
218 except BaseException as err:
219 raise TypeError(
220 f"Failed to convert nodes ({','.join(vlist)}) to type {nodetype}"
221 ) from err
222 G.add_edges_from([(u, v) for v in vlist])
223 return G
226@open_file(0, mode="rb")
227@nx._dispatch(graphs=None)
228def read_adjlist(
229 path,
230 comments="#",
231 delimiter=None,
232 create_using=None,
233 nodetype=None,
234 encoding="utf-8",
235):
236 """Read graph in adjacency list format from path.
238 Parameters
239 ----------
240 path : string or file
241 Filename or file handle to read.
242 Filenames ending in .gz or .bz2 will be uncompressed.
244 create_using : NetworkX graph constructor, optional (default=nx.Graph)
245 Graph type to create. If graph instance, then cleared before populated.
247 nodetype : Python type, optional
248 Convert nodes to this type.
250 comments : string, optional
251 Marker for comment lines
253 delimiter : string, optional
254 Separator for node labels. The default is whitespace.
256 Returns
257 -------
258 G: NetworkX graph
259 The graph corresponding to the lines in adjacency list format.
261 Examples
262 --------
263 >>> G = nx.path_graph(4)
264 >>> nx.write_adjlist(G, "test.adjlist")
265 >>> G = nx.read_adjlist("test.adjlist")
267 The path can be a filehandle or a string with the name of the file. If a
268 filehandle is provided, it has to be opened in 'rb' mode.
270 >>> fh = open("test.adjlist", "rb")
271 >>> G = nx.read_adjlist(fh)
273 Filenames ending in .gz or .bz2 will be compressed.
275 >>> nx.write_adjlist(G, "test.adjlist.gz")
276 >>> G = nx.read_adjlist("test.adjlist.gz")
278 The optional nodetype is a function to convert node strings to nodetype.
280 For example
282 >>> G = nx.read_adjlist("test.adjlist", nodetype=int)
284 will attempt to convert all nodes to integer type.
286 Since nodes must be hashable, the function nodetype must return hashable
287 types (e.g. int, float, str, frozenset - or tuples of those, etc.)
289 The optional create_using parameter indicates the type of NetworkX graph
290 created. The default is `nx.Graph`, an undirected graph.
291 To read the data as a directed graph use
293 >>> G = nx.read_adjlist("test.adjlist", create_using=nx.DiGraph)
295 Notes
296 -----
297 This format does not store graph or node data.
299 See Also
300 --------
301 write_adjlist
302 """
303 lines = (line.decode(encoding) for line in path)
304 return parse_adjlist(
305 lines,
306 comments=comments,
307 delimiter=delimiter,
308 create_using=create_using,
309 nodetype=nodetype,
310 )