Graph library for Python

geremy condra debatem1 at gmail.com
Tue Dec 8 22:47:03 EST 2009


On Tue, Dec 8, 2009 at 8:42 PM, Rhodri James
<rhodri at wildebst.demon.co.uk> wrote:
> On Tue, 08 Dec 2009 04:28:05 -0000, geremy condra <debatem1 at gmail.com>
> wrote:
>
>> On Mon, Dec 7, 2009 at 6:28 PM, M.-A. Lemburg <mal at egenix.com> wrote:
>
>>> I wasn't thinking of anything clever :-) ...
>>>
>>> g = Graph(
>>>     [Node("a"), Node("b"), Node("c")],
>>>     [Edge(Node("a"), Node("b"), "ab"),
>>>      Edge(Node("a"), Node("c"), "ac"),
>>>      Edge(Node("b"), Node("c"), "bc"),
>>>     ])
>>>
>>> The main motivation here is to get lists, sets and dicts
>>> play nice together.
>>
>> Generally, we've tried to discourage people from instantiating
>> nodes and edges directly, in favor of having them controlled
>> through the graph. Maybe something along the lines of:
>>
>> g = Graph(nodes=['a', 'b', 'c'], edges=[('a', 'b'), ('a', 'c'), ('b',
>> 'c')])
>>
>> ?
>
> That works fine for simple cases like this, but starts getting unpleasant if
> you want to initialise with attributes.  Under those circumstances using
> Node and Edge explicitly is much cleaner.  The only extra I'd suggest is
> allowing is_directed as a keyword argument, so you can set the default for
> all edges if you want to.
>
> g = Graph(
>    nodes=[Node("a", colour="red"),
>           Node("b", colour="white"),
>           Node("c", colour="blue")],
>    edges=[Edge("a", "b", "ab", weight=2),
>           Edge("a", "c", "ac", is_directed=True),
>           Edge("b", "c", "bc", style="dotted")],
>    is_directed=True)
>
> I could see a use for this tracking a database structure using a constant
> graph, hence all set up in one go for preference.

While I agree with the rationale, I think we need to find another way.
Aesthetics aside, directly instantiating edges by giving only node names
requires that the edge be aware of what graph its in to provide expected
behavior, which creates a bit of a chicken-or-the-egg dilemma.

How about this: the constructor can take any type of iterable, and
assumes that it follows my earlier format unless it specifies a .items()
method, in which case it takes the values as follows:

g = Graph(
    nodes={'a':{'colour':'red'},
               'b':{'colour':'white'},
               'c':{'colour':'blue'}},
    edges={('a', 'b'):{'name':'ab', 'weight':2},
               ('a', 'c'):{'name':'ac'},
               ('b', 'c'):{'name':'bc', 'style':'dotted'}}
)

Geremy Condra



More information about the Python-list mailing list