I have a code snippet in Python that is showing IndexError. I managed to fix this by using try and except command as shown below. Now, the problem I am facing is when code reaches next line i.e. f = max(d, key=lambda n: d[n]). It throws a ValueError: max() arg is an empty sequence. Could you please help me in fixing this code? Many thanks!
from collections import defaultdict
from tokenize import Double
from pandas import*
costs = {'J': {'A': 0,'B': 28,'C': 999},
'K': {'A': 91,'B': 0,'C': 999},
'L': {'A': 42,'B': 76,'C': 0}}
demand = {'A': 2,'B': 6,'C': 34}
cols = sorted(demand.keys())
supply = {'J': 5,'K': 9,'L': 3}
res = dict((k, defaultdict(int)) for k in costs)
g = {}
for x in supply:
g[x] = sorted(costs[x].keys(), key=lambda g: costs[x][g]) # formation of rows
for x in demand:
g[x] = sorted(costs.keys(), key=lambda g: costs[g][x]) #formation of columns
# iterate through matrix to find out row and column difference
while g:
d = {}
for x in demand:
d[x] = (costs[g[x][1]][x] - costs[g[x][0]][x]) if len(g[x]) > 1 else costs[g[x][0]][x]
s = {}
for x in supply:
try:
s[x] = (costs[x][g[x][1]] - costs[x][g[x][0]]) if len(g[x]) > 1 else costs[x][g[x][0]]
print(s[x])
except IndexError:
pass
f = max(d, key=lambda n: d[n])
t = max(s, key=lambda n: s[n])
t, f = (f, g[f][0]) if d[f] > s[t] else (g[t][0], t)
v = min(supply[f], demand[t])
res[f][t] = v
demand[t] -= v
if demand[t] == 0:
for k, n in supply.items():
if n != 0:
g[k].remove(t)
del g[t]
del demand[t]
supply[f] -= v
if supply[f] == 0:
for k, n in demand.items():
if n != 0:
g[k].remove(f)
del g[f]
del supply[f]
# Update costs/supply/demand
for n in cols:
print ("\t", n),
print
CodePudding user response:
As expected, the last loop is on an empty dict. But dict
are evaluated as False
only if they are equal to {}
. While yours is equal to {'C':[]}
(in this particular case).
I added a small function to change the while
condition. Let me know if this is your expected output.
from collections import defaultdict
from tokenize import Double
from pandas import *
costs = {'J': {'A': 0, 'B': 28, 'C': 999},
'K': {'A': 91, 'B': 0, 'C': 999},
'L': {'A': 42, 'B': 76, 'C': 0}}
demand = {'A': 2, 'B': 6, 'C': 34}
cols = sorted(demand.keys())
supply = {'J': 5, 'K': 9, 'L': 3}
res = dict((k, defaultdict(int)) for k in costs)
g = {}
for x in supply:
g[x] = sorted(costs[x].keys(), key=lambda g: costs[x][g]) # formation of rows
for x in demand:
g[x] = sorted(costs.keys(), key=lambda g: costs[g][x]) # formation of columns
def isEmpty(d):
for k in d.keys():
if len(d[k]) > 0:
return False
return True
# iterate through matrix to find out row and column difference
while not isEmpty(g):
d = {}
for x in demand:
d[x] = (costs[g[x][1]][x] - costs[g[x][0]][x]) if len(g[x]) > 1 else costs[g[x][0]][x]
s = {}
for x in supply:
try:
s[x] = (costs[x][g[x][1]] - costs[x][g[x][0]]) if len(g[x]) > 1 else costs[x][g[x][0]]
print(s[x])
except IndexError:
pass
f = max(d, key=lambda n: d[n])
t = max(s, key=lambda n: s[n])
t, f = (f, g[f][0]) if d[f] > s[t] else (g[t][0], t)
v = min(supply[f], demand[t])
res[f][t] = v
demand[t] -= v
if demand[t] == 0:
for k, n in supply.items():
if n != 0:
g[k].remove(t)
del g[t]
del demand[t]
supply[f] -= v
if supply[f] == 0:
for k, n in demand.items():
if n != 0:
g[k].remove(f)
del g[f]
del supply[f]