pythonattributesnetworkxautomatic-updates

Python's Networkx, updating attributes "automatically"


everybody. I'm building a DiGraph using NetworkX and iterating an algorithm over it. In a particular iteration, every node "n" changes a specific attribute, let's say "A_n". Now, every edge concerning to this particular node "n" and a given predecessor "m", has another attribute of interest, that depends on "A_n", let's call it "B_mn". My question is: Is it possible to update "B_mn" "automatically" by modifying "A_n" for all "n","m" in my set of nodes? I mean, not iterating over the nodes, and then over their predecessors, but using kind of a dinamic function "B_mn(A_n)" that changes its value at the very moment "A_n" changes. Is this possible?

I thinking in something like this:

Let X and Y be numbers, let's suppose that

G.node["n"]["A"]=X and G.edge["m"]["n"]["B"]= Y+G.node["n"]["A"]

I want that by changing the value of X, the value of the attribute "B" in the edge would be updated as well.

Thank you very much in advance for your help :)


Solution

  • One problem with this question -> Don't ever delete nodes.

    In your example you are assigning X to G.node["n"]["A"]. If you say:

    G.node["n"]["A"] = 5
    G.node["n"]["A"] = 6
    

    That destroy's data locations and now G.node["n"]["A"] is pointing to a new object with a new memory location.

    Instead of assignment like '=' you need to do an update of X. Which will leave the datatype and memory location in place. Which means you need a datatype which supports ".update()" like a dictionary.

    Everything past here is dependent on your use case:


    If the node data is a value (like an int or float) then you don't have a problem adding them together. You can keep running calculations based on value addition of changes only 1 level deeper than the calculation is being performed.

    However if the node data is an expression of expressions... example G.node.get('n')['A']+ G.node.get('m')['A'] (which G.node.get('m')['A'] is also an expression that needs to be evaluated.)

    then you have one of 2 problems:

    It is possible to do this all within the graph using something like ast.literal_eval() (warning this is not a GOOD idea)

    If you only have one operation to perform (addition?) then there are some tricks you can use like keep a running list of the data locations and then do a sum().