Search code examples
pythonpython-3.xdictionarykeyerror

KeyError: 2 When using large values


So I had to write a program to sort the SAMPLE ID NO's of plants according to their heights into a list (ascending order of heights), I made a code and it works only for small values. When I put large values, it shows:

Traceback (most recent call last):
  File "C:/Python34/plant_hieght_id.py", line 15, in <module>
  del d[int(w[0])]
KeyError: 2

My code can be found at: http://pastebin.com/embed_js.php?i=TXQ94tUy


Solution

  • I had to write a program to sort the SAMPLE ID NO's of plants according to their heights into a list (ascending order of heights)

    So if d contains the mapping of ids to heights and you want to obtain a sequence of ids sorted by ascending order of height you want to do:

    e = sorted(d, key=lambda k: d[k], reverse=True)
    
    • Iterating over a dictionary iterates over the keys so sorted(d) is the same as sorted(d.keys()).

    • By specifying key=lambda k: d[k] you can customize how the comparisons are performed. Here the comparisons are done on the values d[k] instead of the keys

    • Using reverse=True the sorting is in descending order. (In your question text you say ascending order but the code you provide doesn't do that. If it's really ascending that you want just remove the reverse=True parameter)


    The problem with your original code is that:

    w=list(d.fromkeys(str(q)))
    

    The fromkeys methods accepts an iterable and creates a new dictionary with values set to that iterable.

    In this case q is a number, suppose it is 123. str(q) is the string "123". So d.fromkeys(str(q)) is the dictionary {'1': None, '2': None, '3': None }.

    You the set w to the list of the keys. So w is ['1', '2', '3'].

    In the end d[int(w[0])] tries to delete the key 1. But the code provides no guarantee that this key exist!

    When you entered the values in your previous loop you may not have inserted any 1 key!

    From the code I guess that you want to obtain the maximum value and remove it.

    If you wanted to remove the maximum element you should have done:

    key, val = max(d.items(), key=lambda x_y: x_y[1])
    del d[key]
    

    here max finds the (key, value) pair inside the dictionary with the maximum value and then deletes it.