Shared code block followed by different block for mutually exclusive predicates
What is the best way to express this code? (It was difficult to phrase in words) if cond1 or cond2: # shared code if cond1: # cond1 code else: # cond2 code The above obviously duplicates the check if cond1: # shared # cond1 elif cond2: # shared # cond2 This repeats the shared code I am writing an implementation of Dijkstra's, the question arises within the relax function def dijkstra(s): def relax(w, v, edge_cost): w_via_v = distance[v] + edge_cost if w not in distance: distance[w] = w_via_v toexplore.push(w) elif w_via_v < distance[w]: distance[w] = w_via_v toexplore.update(w) distance = {s: 0} toexplore = PriorityQueue([s], sortkey=lambda v: distance[v]) while not toexplore.is_empty(): v = toexplore.popmin() # Assert: v.distance is distance(s to v) # Assert: thus, v is never put back into toexplore for w, edge_cost in v.neighbours: relax(w, v, edge_cost) Another alternative is def relax(w, v, edge_cost): if w not in distance: distance[w] = ∞ toexplore.push(w) w_via_v = distance[v] + edge_cost if w_via_v < distance[w]: distance[w] = w_via_v toexplore.update(w) But this unnecessarily pushes a node into the priority queue only to update it again
What is the best way to express this code? (It was difficult to phrase in words)
if cond1 or cond2:
# shared code
if cond1:
# cond1 code
else:
# cond2 code
The above obviously duplicates the check
if cond1:
# shared
# cond1
elif cond2:
# shared
# cond2
This repeats the shared code
I am writing an implementation of Dijkstra's, the question arises within the relax
function
def dijkstra(s):
def relax(w, v, edge_cost):
w_via_v = distance[v] + edge_cost
if w not in distance:
distance[w] = w_via_v
toexplore.push(w)
elif w_via_v < distance[w]:
distance[w] = w_via_v
toexplore.update(w)
distance = {s: 0}
toexplore = PriorityQueue([s], sortkey=lambda v: distance[v])
while not toexplore.is_empty():
v = toexplore.popmin()
# Assert: v.distance is distance(s to v)
# Assert: thus, v is never put back into toexplore
for w, edge_cost in v.neighbours:
relax(w, v, edge_cost)
Another alternative is
def relax(w, v, edge_cost):
if w not in distance:
distance[w] = ∞
toexplore.push(w)
w_via_v = distance[v] + edge_cost
if w_via_v < distance[w]:
distance[w] = w_via_v
toexplore.update(w)
But this unnecessarily pushes a node into the priority queue only to update it again