I've written the following code to reverse the edges of a graph, expressed as an adjacency list Mapping
.
from typing import Mapping, Any, Sized
from collections import defaultdict
def edge_reversed_graph(g: Mapping[Any, Sized]):
d = defaultdict(set)
for src, dst_nodes in g.items():
if len(dst_nodes):
for dst in dst_nodes:
d[dst].add(src)
elif src not in d:
d[src] = set()
return d
Example:
>>> graph = dict(a='c', b='cd', c='abd', e='')
>>> assert edge_reversed_graph(graph) == {'c': {'a', 'b'}, 'd': {'c', 'b'}, 'a': {'c'}, 'b': {'c'}, 'e': set()}
I'd like to be able to just require the graph to be Mapping[Any, Iterable]
, that is the adjacency "list" not to necessarily have to have a length. This is achievable using a flag variable, but I'm looking for a more elegant and efficient solution, otherwise making the function work with a larger group of objects wouldn't be worth it to me.
Checking whether the container/iterable of outgoing edges is empty is a red herring: Each node must always be ensured to exist.
This removes the need to check whether there are outgoing edges: Always add the src
node if it does not exist . Always iterate all outgoing edges, of which there might be none.
from typing import Mapping, TypeVar, Iterable, Set
from collections import defaultdict
T = TypeVar('T')
def edge_reversed_graph(g: Mapping[T, Iterable[T]]) -> Mapping[T, Set[T]]:
d = defaultdict(set)
for src, dst_nodes in g.items():
d.setdefault(src, set()) # add node if not present
for dst in dst_nodes: # empty iterable does nothing
d[dst].add(src)
return d
Similar to what I assume you mean with flag (having a bool
variable set to True
inside the loop), but more efficient:
def edge_reversed_graph(g: Mapping[Any, Iterable]):
d = defaultdict(set)
none = object()
for src, dst_nodes in g.items():
dst = none
for dst in dst_nodes:
d[dst].add(src)
if dst is none:
d[src] = set()
return d
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.