-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathedges.py
More file actions
156 lines (148 loc) · 4.88 KB
/
edges.py
File metadata and controls
156 lines (148 loc) · 4.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
from collections import MappingView, Set
from networkx.exception import NetworkXError
class BaseEdgeView(Set):
__slots__ = ["_edgesobj"]
def __init__(self, edgesobj):
self._edgesobj = edgesobj
def __repr__(self):
return '{0.__class__.__name__}({1})'.format(self,list(self))
def __len__(self):
return len(self._edgesobj)
# Set also demands __iter__ and __contains__ be defined.
class EdgeKeys(BaseEdgeView):
__slots__ = ["_edgesobj"]
def __iter__(self):
return iter(self._edgesobj)
def __contains__(self, key):
u,v = key
return v in self._edgesobj._adj[u]
class EdgeData(BaseEdgeView):
__slots__ = ["_edgesobj"]
def __iter__(self):
for e,d in self._edgesobj._items():
yield d
def __contains__(self, data):
# Do we need/want to provide ability to look up a datadict?
# need to look at all data
for d in self:
if d == data:
return True
return False
class EdgeItems(BaseEdgeView):
__slots__ = ["_edgesobj"]
def __iter__(self):
return self._edgesobj._items()
def __contains__(self, key):
adj = self._edgesobj._adj
(u,v),d = key
return v in adj[u] and adj[u][v] == d
class UndirectedEdges(object):
def __len__(self):
return sum(len(nbrs) for n, nbrs in self._adj.items()) // 2
def __iter__(self):
seen = set()
nodes_nbrs = self._adj.items()
for n, nbrs in nodes_nbrs:
for nbr in nbrs:
if nbr not in seen:
yield (n, nbr)
seen.add(n)
del seen
def _items(self):
seen = set()
nodes_nbrs = self._adj.items()
for n, nbrs in nodes_nbrs:
for nbr, ddict in nbrs.items():
if nbr not in seen:
yield (n,nbr),ddict
seen.add(n)
del seen
def __contains__(self, key):
u,v = key
return v in self._adj[u]
def __getitem__(self, key):
try:
u,v = key
return self._adj[u][v]
except TypeError:
raise NetworkXError('bad edge key: use edge key = (u,v)')
# Mutating Methods
def add(self, u, v, attr_dict=None, **attr):
if attr_dict is None:
attr_dict = attr
else:
try:
attr_dict.update(attr)
except AttributeError:
raise NetworkXError(
"The attr_dict argument must be a dictionary.")
# add nodes
if u not in self._node:
self._adj[u] = {} # fixme factory
self._node[u] = {}
if v not in self._node:
self._adj[v] = {} # fixme factory
self._node[v] = {}
# add the edge
datadict = self._adj[u].get(v, {}) # fixme factory
datadict.update(attr_dict)
self._adj[u][v] = datadict
self._adj[v][u] = datadict
def update(self, ebunch, attr_dict=None, **attr):
# set up attribute dict
if attr_dict is None:
attr_dict = attr
else:
try:
attr_dict.update(attr)
except AttributeError:
raise NetworkXError(
"The attr_dict argument must be a dictionary.")
# process ebunch
for e in ebunch:
ne = len(e)
if ne == 3:
u, v, dd = e
elif ne == 2:
u, v = e
dd = {} # doesnt need edge_attr_dict_factory
else:
raise NetworkXError(
"Edge tuple %s must be a 2-tuple or 3-tuple." % (e,))
if u not in self._node:
self._adj[u] = {}
self._node[u] = {}
if v not in self._node:
self._adj[v] = {}
self._node[v] = {}
datadict = self._adj[u].get(v, {})
datadict.update(attr_dict)
datadict.update(dd)
self._adj[u][v] = datadict
self._adj[v][u] = datadict
def remove(self, u, v):
try:
del self._adj[u][v]
if u != v: # self-loop needs only one entry removed
del self._adj[v][u]
except KeyError:
raise NetworkXError("The edge %s-%s is not in the graph" % (u, v))
def clear(self):
for n in self._adj:
self._adj[n].clear()
class Edges(UndirectedEdges, Set):
__slots__ = ('_adj','_node')
def __init__(self, node, adj):
self._adj = adj
self._node = node
def __repr__(self):
return '{0.__class__.__name__}({1})'.format(self,list(self))
def keys(self):
return EdgeKeys(self)
def data(self):
return EdgeData(self)
def items(self):
return EdgeItems(self)
def selfloops(self):
return ((n, n)
for n, nbrs in self._adj.items() if n in nbrs)