I have the following python code:
import networkx as nx
def cost(i, j, d, value1, value2):
# some operation involving all these values
return cost
# graph is a networkx graph
# src, dst are integers
# cost is a callable that is passed 3 values automatically i.e. src, dst and d
# d is a dictionary of edge weights
path = nx.dijkstra_path(graph, src, dst, weight=cost)
Now I want to pass two values value1 and value2 to the cost function.
The networkx documentation says the weight can be a callable that accepts exactly 3 arguments. But i need value1 and value2 for calculations. How can this be done?
Edit The solution using functools works well. However, my function is in a class as follows:
import networkx as nx
import functools
class Myclass:
def cost(self, i, j, d, value2):
# some operation involving all these values
# also need self
# graph is a networkx graph
# src, dst are integers
# cost is a callable that is passed 3 values automatically i.e. src, dst and d
# d is a dictionary of edge weights
# path = nx.dijkstra_path(graph, src, dst, cost)
cost_partial = functools.partial(cost, self=self, value2=5)
path = nx.dijkstra_path(graph, src, dst, cost_partial)
Using this approach, nx.dijkstra_path insists upon assigning src to self. Thus the interpreter complains that self is assigned multiple values.
I need self for calculating the cost.
You just need a function that wraps cost. A quick way is to use functools.partial.
import functools
def cost(i, j, d, value1, value2):
'Example function'
return i, j, d, value1, value2
# This makes a new function which takes all parameters of `cost` except those
# you've already passed. Here I'm going to set value1 and value2 to 1 and 2
# respectively.
cost_partial = functools.partial(cost, value1=1, value2=2)
# A new function that only accepts the 3 args i, j, d
cost_partial('i', 'j', 'd') # --> ('i', 'j', 'd', 1, 2)
# use as
path = nx.dijkstra_path(graph, src, dst, weight=cost_partial)
This depends largely on the meaning on the meaning of value1 and value2. I would suggest adding a wrapper callable by networkx:
def cost_wrapper(i, j, d):
value1 = 0 # set values as needed
value2 = 1
return cost(i, j, d, value1, value2)
And provide it to networkx:
path = nx.dijkstra_path(graph, src, dst, weight=cost_wrapper)
Or simply make them global variables, not arguments.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With