comparison env/lib/python3.9/site-packages/networkx/classes/coreviews.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 from collections.abc import Mapping
4
5 __all__ = [
6 "AtlasView",
7 "AdjacencyView",
8 "MultiAdjacencyView",
9 "UnionAtlas",
10 "UnionAdjacency",
11 "UnionMultiInner",
12 "UnionMultiAdjacency",
13 "FilterAtlas",
14 "FilterAdjacency",
15 "FilterMultiInner",
16 "FilterMultiAdjacency",
17 ]
18
19
20 class AtlasView(Mapping):
21 """An AtlasView is a Read-only Mapping of Mappings.
22
23 It is a View into a dict-of-dict data structure.
24 The inner level of dict is read-write. But the
25 outer level is read-only.
26
27 See Also
28 ========
29 AdjacencyView - View into dict-of-dict-of-dict
30 MultiAdjacencyView - View into dict-of-dict-of-dict-of-dict
31 """
32
33 __slots__ = ("_atlas",)
34
35 def __getstate__(self):
36 return {"_atlas": self._atlas}
37
38 def __setstate__(self, state):
39 self._atlas = state["_atlas"]
40
41 def __init__(self, d):
42 self._atlas = d
43
44 def __len__(self):
45 return len(self._atlas)
46
47 def __iter__(self):
48 return iter(self._atlas)
49
50 def __getitem__(self, key):
51 return self._atlas[key]
52
53 def copy(self):
54 return {n: self[n].copy() for n in self._atlas}
55
56 def __str__(self):
57 return str(self._atlas) # {nbr: self[nbr] for nbr in self})
58
59 def __repr__(self):
60 return f"{self.__class__.__name__}({self._atlas!r})"
61
62
63 class AdjacencyView(AtlasView):
64 """An AdjacencyView is a Read-only Map of Maps of Maps.
65
66 It is a View into a dict-of-dict-of-dict data structure.
67 The inner level of dict is read-write. But the
68 outer levels are read-only.
69
70 See Also
71 ========
72 AtlasView - View into dict-of-dict
73 MultiAdjacencyView - View into dict-of-dict-of-dict-of-dict
74 """
75
76 __slots__ = () # Still uses AtlasView slots names _atlas
77
78 def __getitem__(self, name):
79 return AtlasView(self._atlas[name])
80
81 def copy(self):
82 return {n: self[n].copy() for n in self._atlas}
83
84
85 class MultiAdjacencyView(AdjacencyView):
86 """An MultiAdjacencyView is a Read-only Map of Maps of Maps of Maps.
87
88 It is a View into a dict-of-dict-of-dict-of-dict data structure.
89 The inner level of dict is read-write. But the
90 outer levels are read-only.
91
92 See Also
93 ========
94 AtlasView - View into dict-of-dict
95 AdjacencyView - View into dict-of-dict-of-dict
96 """
97
98 __slots__ = () # Still uses AtlasView slots names _atlas
99
100 def __getitem__(self, name):
101 return AdjacencyView(self._atlas[name])
102
103 def copy(self):
104 return {n: self[n].copy() for n in self._atlas}
105
106
107 class UnionAtlas(Mapping):
108 """A read-only union of two atlases (dict-of-dict).
109
110 The two dict-of-dicts represent the inner dict of
111 an Adjacency: `G.succ[node]` and `G.pred[node]`.
112 The inner level of dict of both hold attribute key:value
113 pairs and is read-write. But the outer level is read-only.
114
115 See Also
116 ========
117 UnionAdjacency - View into dict-of-dict-of-dict
118 UnionMultiAdjacency - View into dict-of-dict-of-dict-of-dict
119 """
120
121 __slots__ = ("_succ", "_pred")
122
123 def __getstate__(self):
124 return {"_succ": self._succ, "_pred": self._pred}
125
126 def __setstate__(self, state):
127 self._succ = state["_succ"]
128 self._pred = state["_pred"]
129
130 def __init__(self, succ, pred):
131 self._succ = succ
132 self._pred = pred
133
134 def __len__(self):
135 return len(self._succ) + len(self._pred)
136
137 def __iter__(self):
138 return iter(set(self._succ.keys()) | set(self._pred.keys()))
139
140 def __getitem__(self, key):
141 try:
142 return self._succ[key]
143 except KeyError:
144 return self._pred[key]
145
146 def copy(self):
147 result = {nbr: dd.copy() for nbr, dd in self._succ.items()}
148 for nbr, dd in self._pred.items():
149 if nbr in result:
150 result[nbr].update(dd)
151 else:
152 result[nbr] = dd.copy()
153 return result
154
155 def __str__(self):
156 return str({nbr: self[nbr] for nbr in self})
157
158 def __repr__(self):
159 return f"{self.__class__.__name__}({self._succ!r}, {self._pred!r})"
160
161
162 class UnionAdjacency(Mapping):
163 """A read-only union of dict Adjacencies as a Map of Maps of Maps.
164
165 The two input dict-of-dict-of-dicts represent the union of
166 `G.succ` and `G.pred`. Return values are UnionAtlas
167 The inner level of dict is read-write. But the
168 middle and outer levels are read-only.
169
170 succ : a dict-of-dict-of-dict {node: nbrdict}
171 pred : a dict-of-dict-of-dict {node: nbrdict}
172 The keys for the two dicts should be the same
173
174 See Also
175 ========
176 UnionAtlas - View into dict-of-dict
177 UnionMultiAdjacency - View into dict-of-dict-of-dict-of-dict
178 """
179
180 __slots__ = ("_succ", "_pred")
181
182 def __getstate__(self):
183 return {"_succ": self._succ, "_pred": self._pred}
184
185 def __setstate__(self, state):
186 self._succ = state["_succ"]
187 self._pred = state["_pred"]
188
189 def __init__(self, succ, pred):
190 # keys must be the same for two input dicts
191 assert len(set(succ.keys()) ^ set(pred.keys())) == 0
192 self._succ = succ
193 self._pred = pred
194
195 def __len__(self):
196 return len(self._succ) # length of each dict should be the same
197
198 def __iter__(self):
199 return iter(self._succ)
200
201 def __getitem__(self, nbr):
202 return UnionAtlas(self._succ[nbr], self._pred[nbr])
203
204 def copy(self):
205 return {n: self[n].copy() for n in self._succ}
206
207 def __str__(self):
208 return str({nbr: self[nbr] for nbr in self})
209
210 def __repr__(self):
211 return f"{self.__class__.__name__}({self._succ!r}, {self._pred!r})"
212
213
214 class UnionMultiInner(UnionAtlas):
215 """A read-only union of two inner dicts of MultiAdjacencies.
216
217 The two input dict-of-dict-of-dicts represent the union of
218 `G.succ[node]` and `G.pred[node]` for MultiDiGraphs.
219 Return values are UnionAtlas.
220 The inner level of dict is read-write. But the outer levels are read-only.
221
222 See Also
223 ========
224 UnionAtlas - View into dict-of-dict
225 UnionAdjacency - View into dict-of-dict-of-dict
226 UnionMultiAdjacency - View into dict-of-dict-of-dict-of-dict
227 """
228
229 __slots__ = () # Still uses UnionAtlas slots names _succ, _pred
230
231 def __getitem__(self, node):
232 in_succ = node in self._succ
233 in_pred = node in self._pred
234 if in_succ:
235 if in_pred:
236 return UnionAtlas(self._succ[node], self._pred[node])
237 return UnionAtlas(self._succ[node], {})
238 return UnionAtlas({}, self._pred[node])
239
240 def copy(self):
241 nodes = set(self._succ.keys()) | set(self._pred.keys())
242 return {n: self[n].copy() for n in nodes}
243
244
245 class UnionMultiAdjacency(UnionAdjacency):
246 """A read-only union of two dict MultiAdjacencies.
247
248 The two input dict-of-dict-of-dict-of-dicts represent the union of
249 `G.succ` and `G.pred` for MultiDiGraphs. Return values are UnionAdjacency.
250 The inner level of dict is read-write. But the outer levels are read-only.
251
252 See Also
253 ========
254 UnionAtlas - View into dict-of-dict
255 UnionMultiInner - View into dict-of-dict-of-dict
256 """
257
258 __slots__ = () # Still uses UnionAdjacency slots names _succ, _pred
259
260 def __getitem__(self, node):
261 return UnionMultiInner(self._succ[node], self._pred[node])
262
263
264 class FilterAtlas(Mapping): # nodedict, nbrdict, keydict
265 def __init__(self, d, NODE_OK):
266 self._atlas = d
267 self.NODE_OK = NODE_OK
268
269 def __len__(self):
270 return sum(1 for n in self)
271
272 def __iter__(self):
273 try: # check that NODE_OK has attr 'nodes'
274 node_ok_shorter = 2 * len(self.NODE_OK.nodes) < len(self._atlas)
275 except AttributeError:
276 node_ok_shorter = False
277 if node_ok_shorter:
278 return (n for n in self.NODE_OK.nodes if n in self._atlas)
279 return (n for n in self._atlas if self.NODE_OK(n))
280
281 def __getitem__(self, key):
282 if key in self._atlas and self.NODE_OK(key):
283 return self._atlas[key]
284 raise KeyError(f"Key {key} not found")
285
286 def copy(self):
287 try: # check that NODE_OK has attr 'nodes'
288 node_ok_shorter = 2 * len(self.NODE_OK.nodes) < len(self._atlas)
289 except AttributeError:
290 node_ok_shorter = False
291 if node_ok_shorter:
292 return {u: self._atlas[u] for u in self.NODE_OK.nodes if u in self._atlas}
293 return {u: d for u, d in self._atlas.items() if self.NODE_OK(u)}
294
295 def __str__(self):
296 return str({nbr: self[nbr] for nbr in self})
297
298 def __repr__(self):
299 return f"{self.__class__.__name__}({self._atlas!r}, {self.NODE_OK!r})"
300
301
302 class FilterAdjacency(Mapping): # edgedict
303 def __init__(self, d, NODE_OK, EDGE_OK):
304 self._atlas = d
305 self.NODE_OK = NODE_OK
306 self.EDGE_OK = EDGE_OK
307
308 def __len__(self):
309 return sum(1 for n in self)
310
311 def __iter__(self):
312 try: # check that NODE_OK has attr 'nodes'
313 node_ok_shorter = 2 * len(self.NODE_OK.nodes) < len(self._atlas)
314 except AttributeError:
315 node_ok_shorter = False
316 if node_ok_shorter:
317 return (n for n in self.NODE_OK.nodes if n in self._atlas)
318 return (n for n in self._atlas if self.NODE_OK(n))
319
320 def __getitem__(self, node):
321 if node in self._atlas and self.NODE_OK(node):
322
323 def new_node_ok(nbr):
324 return self.NODE_OK(nbr) and self.EDGE_OK(node, nbr)
325
326 return FilterAtlas(self._atlas[node], new_node_ok)
327 raise KeyError(f"Key {node} not found")
328
329 def copy(self):
330 try: # check that NODE_OK has attr 'nodes'
331 node_ok_shorter = 2 * len(self.NODE_OK.nodes) < len(self._atlas)
332 except AttributeError:
333 node_ok_shorter = False
334 if node_ok_shorter:
335 return {
336 u: {
337 v: d
338 for v, d in self._atlas[u].items()
339 if self.NODE_OK(v)
340 if self.EDGE_OK(u, v)
341 }
342 for u in self.NODE_OK.nodes
343 if u in self._atlas
344 }
345 return {
346 u: {v: d for v, d in nbrs.items() if self.NODE_OK(v) if self.EDGE_OK(u, v)}
347 for u, nbrs in self._atlas.items()
348 if self.NODE_OK(u)
349 }
350
351 def __str__(self):
352 return str({nbr: self[nbr] for nbr in self})
353
354 def __repr__(self):
355 name = self.__class__.__name__
356 return f"{name}({self._atlas!r}, {self.NODE_OK!r}, {self.EDGE_OK!r})"
357
358
359 class FilterMultiInner(FilterAdjacency): # muliedge_seconddict
360 def __iter__(self):
361 try: # check that NODE_OK has attr 'nodes'
362 node_ok_shorter = 2 * len(self.NODE_OK.nodes) < len(self._atlas)
363 except AttributeError:
364 node_ok_shorter = False
365 if node_ok_shorter:
366 my_nodes = (n for n in self.NODE_OK.nodes if n in self._atlas)
367 else:
368 my_nodes = (n for n in self._atlas if self.NODE_OK(n))
369 for n in my_nodes:
370 some_keys_ok = False
371 for key in self._atlas[n]:
372 if self.EDGE_OK(n, key):
373 some_keys_ok = True
374 break
375 if some_keys_ok is True:
376 yield n
377
378 def __getitem__(self, nbr):
379 if nbr in self._atlas and self.NODE_OK(nbr):
380
381 def new_node_ok(key):
382 return self.EDGE_OK(nbr, key)
383
384 return FilterAtlas(self._atlas[nbr], new_node_ok)
385 raise KeyError(f"Key {nbr} not found")
386
387 def copy(self):
388 try: # check that NODE_OK has attr 'nodes'
389 node_ok_shorter = 2 * len(self.NODE_OK.nodes) < len(self._atlas)
390 except AttributeError:
391 node_ok_shorter = False
392 if node_ok_shorter:
393 return {
394 v: {k: d for k, d in self._atlas[v].items() if self.EDGE_OK(v, k)}
395 for v in self.NODE_OK.nodes
396 if v in self._atlas
397 }
398 return {
399 v: {k: d for k, d in nbrs.items() if self.EDGE_OK(v, k)}
400 for v, nbrs in self._atlas.items()
401 if self.NODE_OK(v)
402 }
403
404
405 class FilterMultiAdjacency(FilterAdjacency): # multiedgedict
406 def __getitem__(self, node):
407 if node in self._atlas and self.NODE_OK(node):
408
409 def edge_ok(nbr, key):
410 return self.NODE_OK(nbr) and self.EDGE_OK(node, nbr, key)
411
412 return FilterMultiInner(self._atlas[node], self.NODE_OK, edge_ok)
413 raise KeyError(f"Key {node} not found")
414
415 def copy(self):
416 try: # check that NODE_OK has attr 'nodes'
417 node_ok_shorter = 2 * len(self.NODE_OK.nodes) < len(self._atlas)
418 except AttributeError:
419 node_ok_shorter = False
420 if node_ok_shorter:
421 my_nodes = self.NODE_OK.nodes
422 return {
423 u: {
424 v: {k: d for k, d in kd.items() if self.EDGE_OK(u, v, k)}
425 for v, kd in self._atlas[u].items()
426 if v in my_nodes
427 }
428 for u in my_nodes
429 if u in self._atlas
430 }
431 return {
432 u: {
433 v: {k: d for k, d in kd.items() if self.EDGE_OK(u, v, k)}
434 for v, kd in nbrs.items()
435 if self.NODE_OK(v)
436 }
437 for u, nbrs in self._atlas.items()
438 if self.NODE_OK(u)
439 }