Home > Software design >  IndexError: List index out or range fix and ValueError
IndexError: List index out or range fix and ValueError

Time:04-21

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]
  • Related