comparison env/lib/python3.9/site-packages/networkx/readwrite/adjlist.py @ 0:4f3585e2f14b draft default tip

"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author shellac
date Mon, 22 Mar 2021 18:12:50 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4f3585e2f14b
1 """
2 **************
3 Adjacency List
4 **************
5 Read and write NetworkX graphs as adjacency lists.
6
7 Adjacency list format is useful for graphs without data associated
8 with nodes or edges and for nodes that can be meaningfully represented
9 as strings.
10
11 Format
12 ------
13 The adjacency list format consists of lines with node labels. The
14 first label in a line is the source node. Further labels in the line
15 are considered target nodes and are added to the graph along with an edge
16 between the source node and target node.
17
18 The graph with edges a-b, a-c, d-e can be represented as the following
19 adjacency list (anything following the # in a line is a comment)::
20
21 a b c # source target target
22 d e
23 """
24
25 __all__ = ["generate_adjlist", "write_adjlist", "parse_adjlist", "read_adjlist"]
26
27 from networkx.utils import open_file
28 import networkx as nx
29
30
31 def generate_adjlist(G, delimiter=" "):
32 """Generate a single line of the graph G in adjacency list format.
33
34 Parameters
35 ----------
36 G : NetworkX graph
37
38 delimiter : string, optional
39 Separator for node labels
40
41 Returns
42 -------
43 lines : string
44 Lines of data in adjlist format.
45
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
58
59 See Also
60 --------
61 write_adjlist, read_adjlist
62
63 """
64 directed = G.is_directed()
65 seen = set()
66 for s, nbrs in G.adjacency():
67 line = str(s) + delimiter
68 for t, data in nbrs.items():
69 if not directed and t in seen:
70 continue
71 if G.is_multigraph():
72 for d in data.values():
73 line += str(t) + delimiter
74 else:
75 line += str(t) + delimiter
76 if not directed:
77 seen.add(s)
78 yield line[: -len(delimiter)]
79
80
81 @open_file(1, mode="wb")
82 def write_adjlist(G, path, comments="#", delimiter=" ", encoding="utf-8"):
83 """Write graph G in single-line adjacency-list format to path.
84
85
86 Parameters
87 ----------
88 G : NetworkX graph
89
90 path : string or file
91 Filename or file handle for data output.
92 Filenames ending in .gz or .bz2 will be compressed.
93
94 comments : string, optional
95 Marker for comment lines
96
97 delimiter : string, optional
98 Separator for node labels
99
100 encoding : string, optional
101 Text encoding.
102
103 Examples
104 --------
105 >>> G = nx.path_graph(4)
106 >>> nx.write_adjlist(G, "test.adjlist")
107
108 The path can be a filehandle or a string with the name of the file. If a
109 filehandle is provided, it has to be opened in 'wb' mode.
110
111 >>> fh = open("test.adjlist", "wb")
112 >>> nx.write_adjlist(G, fh)
113
114 Notes
115 -----
116 This format does not store graph, node, or edge data.
117
118 See Also
119 --------
120 read_adjlist, generate_adjlist
121 """
122 import sys
123 import time
124
125 pargs = comments + " ".join(sys.argv) + "\n"
126 header = (
127 pargs
128 + comments
129 + f" GMT {time.asctime(time.gmtime())}\n"
130 + comments
131 + f" {G.name}\n"
132 )
133 path.write(header.encode(encoding))
134
135 for line in generate_adjlist(G, delimiter):
136 line += "\n"
137 path.write(line.encode(encoding))
138
139
140 def parse_adjlist(
141 lines, comments="#", delimiter=None, create_using=None, nodetype=None
142 ):
143 """Parse lines of a graph adjacency list representation.
144
145 Parameters
146 ----------
147 lines : list or iterator of strings
148 Input data in adjlist format
149
150 create_using : NetworkX graph constructor, optional (default=nx.Graph)
151 Graph type to create. If graph instance, then cleared before populated.
152
153 nodetype : Python type, optional
154 Convert nodes to this type.
155
156 comments : string, optional
157 Marker for comment lines
158
159 delimiter : string, optional
160 Separator for node labels. The default is whitespace.
161
162 Returns
163 -------
164 G: NetworkX graph
165 The graph corresponding to the lines in adjacency list format.
166
167 Examples
168 --------
169 >>> lines = ["1 2 5", "2 3 4", "3 5", "4", "5"]
170 >>> G = nx.parse_adjlist(lines, nodetype=int)
171 >>> nodes = [1, 2, 3, 4, 5]
172 >>> all(node in G for node in nodes)
173 True
174 >>> edges = [(1, 2), (1, 5), (2, 3), (2, 4), (3, 5)]
175 >>> all((u, v) in G.edges() or (v, u) in G.edges() for (u, v) in edges)
176 True
177
178 See Also
179 --------
180 read_adjlist
181
182 """
183 G = nx.empty_graph(0, create_using)
184 for line in lines:
185 p = line.find(comments)
186 if p >= 0:
187 line = line[:p]
188 if not len(line):
189 continue
190 vlist = line.strip().split(delimiter)
191 u = vlist.pop(0)
192 # convert types
193 if nodetype is not None:
194 try:
195 u = nodetype(u)
196 except BaseException as e:
197 raise TypeError(
198 f"Failed to convert node ({u}) to type " f"{nodetype}"
199 ) from e
200 G.add_node(u)
201 if nodetype is not None:
202 try:
203 vlist = list(map(nodetype, vlist))
204 except BaseException as e:
205 raise TypeError(
206 f"Failed to convert nodes ({','.join(vlist)}) "
207 f"to type {nodetype}"
208 ) from e
209 G.add_edges_from([(u, v) for v in vlist])
210 return G
211
212
213 @open_file(0, mode="rb")
214 def read_adjlist(
215 path,
216 comments="#",
217 delimiter=None,
218 create_using=None,
219 nodetype=None,
220 encoding="utf-8",
221 ):
222 """Read graph in adjacency list format from path.
223
224 Parameters
225 ----------
226 path : string or file
227 Filename or file handle to read.
228 Filenames ending in .gz or .bz2 will be uncompressed.
229
230 create_using : NetworkX graph constructor, optional (default=nx.Graph)
231 Graph type to create. If graph instance, then cleared before populated.
232
233 nodetype : Python type, optional
234 Convert nodes to this type.
235
236 comments : string, optional
237 Marker for comment lines
238
239 delimiter : string, optional
240 Separator for node labels. The default is whitespace.
241
242 Returns
243 -------
244 G: NetworkX graph
245 The graph corresponding to the lines in adjacency list format.
246
247 Examples
248 --------
249 >>> G = nx.path_graph(4)
250 >>> nx.write_adjlist(G, "test.adjlist")
251 >>> G = nx.read_adjlist("test.adjlist")
252
253 The path can be a filehandle or a string with the name of the file. If a
254 filehandle is provided, it has to be opened in 'rb' mode.
255
256 >>> fh = open("test.adjlist", "rb")
257 >>> G = nx.read_adjlist(fh)
258
259 Filenames ending in .gz or .bz2 will be compressed.
260
261 >>> nx.write_adjlist(G, "test.adjlist.gz")
262 >>> G = nx.read_adjlist("test.adjlist.gz")
263
264 The optional nodetype is a function to convert node strings to nodetype.
265
266 For example
267
268 >>> G = nx.read_adjlist("test.adjlist", nodetype=int)
269
270 will attempt to convert all nodes to integer type.
271
272 Since nodes must be hashable, the function nodetype must return hashable
273 types (e.g. int, float, str, frozenset - or tuples of those, etc.)
274
275 The optional create_using parameter indicates the type of NetworkX graph
276 created. The default is `nx.Graph`, an undirected graph.
277 To read the data as a directed graph use
278
279 >>> G = nx.read_adjlist("test.adjlist", create_using=nx.DiGraph)
280
281 Notes
282 -----
283 This format does not store graph or node data.
284
285 See Also
286 --------
287 write_adjlist
288 """
289 lines = (line.decode(encoding) for line in path)
290 return parse_adjlist(
291 lines,
292 comments=comments,
293 delimiter=delimiter,
294 create_using=create_using,
295 nodetype=nodetype,
296 )