Search code examples
pythonnetworkx

how to have access to lists generated through networkx shortest path function


consider the code below :


G2 = nx.DiGraph()

G2.add_edges_from([('A','B'),('A','C'),('F','G'),('A','F'),('F','H'),('A','I')])

nx.draw(G2, with_labels=1)


paths = (nx.all_pairs_shortest_path(G2))

for path in paths :
    print(path)

the output of this code is:

('A', {'A': ['A'], 'B': ['A', 'B'], 'C': ['A', 'C'], 'F': ['A', 'F'], 'I': ['A', 'I'], 'G': ['A', 'F', 'G'], 'H': ['A', 'F', 'H']})
('B', {'B': ['B']})
('C', {'C': ['C']})
('F', {'F': ['F'], 'G': ['F', 'G'], 'H': ['F', 'H']})
('G', {'G': ['G']})
('H', {'H': ['H']})
('I', {'I': ['I']})

I want to know how I can have access to the all lists such as ['A'], ['A', 'B'], ['A', 'C'], ['A', 'F'] , ... and store them in a list.

Thank you.


Solution

  • paths is a generator. It doesn't support item assignment. You might like it to convert to a data structure that does it:

    d = dict(paths)  
    >>> print(d)
    {'A': {'A': ['A'], 'B': ['A', 'B'], 'C': ['A', 'C'], 'F': ['A', 'F'], 'I': ['A', 'I'], 'G': ['A', 'F', 'G'], 'H': ['A', 'F', 'H']}, 'B': {'B': ['B']}, 'C': {'C': ['C']}, 'F': {'F': ['F'], 'G': ['F', 'G'], 'H': ['F', 'H']}, 'G': {'G': ['G']}, 'H': {'H': ['H']}, 'I': {'I': ['I']}}
    

    That's not very presentative. But still, you're able to check specific edges, like:

    >>> d['A']['H']
    ['A', 'F', 'H']
    

    We can also tidy this a little bit to have all possible path traversals:

    from itertools import product
    >>> print(list(product(d.keys(), repeat=2)))
    [('A', 'A'), ('A', 'B'), ('A', 'C'), ..., ('I', 'G'), ('I', 'H'), ('I', 'I')]
    dd = {(a, b): d[a][b] for a, b in product(d.keys(), repeat=2) if b in d[a]}
    >>> dd
    {('A', 'A'): ['A'],
     ('A', 'B'): ['A', 'B'],
     ('A', 'C'): ['A', 'C'],
     ('A', 'F'): ['A', 'F'],
     ('A', 'G'): ['A', 'F', 'G'],
     ('A', 'H'): ['A', 'F', 'H'],
     ('A', 'I'): ['A', 'I'],
     ('B', 'B'): ['B'],
     ('C', 'C'): ['C'],
     ('F', 'F'): ['F'],
     ('F', 'G'): ['F', 'G'],
     ('F', 'H'): ['F', 'H'],
     ('G', 'G'): ['G'],
     ('H', 'H'): ['H'],
     ('I', 'I'): ['I']}
    

    It can be used in a little different way:

    >>> dd['A', 'H']
    ['A', 'F', 'H']
    

    Alternatively, with no itertools:

    dd = {(a, b): d[a][b] for a in d.keys() for b in d.keys() if b in d[a]}
    

    Output should be the same.