pythonsortingdictionarycts

PYTHON3 DICTIONARY - Why First Answer is Incorrect,while Second Answer is Correct


Here, in both cases, my first result is incorrect while my second result is correct. Can anyone please explain to me the reason behind this?

My first Requirement is to order dictionary by value in ascending order first and then by key in descending order

My second Requirement is to order dictionary by value in descending order first and then by key in descending order

I have tried a little, but got stuck in two concepts which did not work for me. I simply want to know the reason why those logics are incorrect.

Thanks in advance

from collections import OrderedDict

#Value Descending and then Key Ascending[Descending means -ve,Ascending means +ve]
def sorted_dict_by_firstValue_secondKey(dictionary,AscendingKey=True,AscendingValue=True,reverse=False):
    Dictionary = OrderedDict()
    keySign = 1
    valSign = 1
    if(AscendingKey==False):
        keySign = -1
    if(AscendingValue==False):
        valSign = -1
    for key,value in sorted(dictionary.items(),key=lambda item: (valSign*item[1],keySign*item[0]),reverse=reverse):
        Dictionary[key] = value
    return Dictionary


album = {'carl':40,'oswald':2,'bob':1,'danny':3,'alice':1,'alan':2,'tom':3,'alquaida':40, 'elizabeth':40}



ValAscKeyDescDictionary1 = sorted_dict_by_firstValue_secondKey(album,AscendingValue=True,AscendingKey=False)
ValAscKeyDescDictionary2 = sorted_dict_by_firstValue_secondKey(album,AscendingValue=False,AscendingKey=True,reverse=True)


ValDescKeyDescDictionary1 = sorted_dict_by_firstValue_secondKey(album,AscendingValue=False,AscendingKey=False)
ValDescKeyDescDictionary2 = sorted_dict_by_firstValue_secondKey(album,reverse=True)

print("--------------------------------------------------------------------------------")
print("\n\nDICTIONARY ASCENDING SORTED BY VALUE AND THEN BY KEYS ALBHABETICALLY DESCENDING FOR SAME VALUES")


print("InCorrect Answer- ",ValAscKeyDescDictionary1)
print("Correct Answer- ",ValAscKeyDescDictionary2)

print("--------------------------------------------------------------------------------")

print("\n\nDICTIONARY DESCENDING SORTED BY VALUE AND THEN BY KEYS ALBHABETICALLY DESCENDING FOR SAME VALUES")

print("InCorrect Answer- ",ValDescKeyDescDictionary1)
print("Correct Answer- ",ValDescKeyDescDictionary2)

print("--------------------------------------------------------------------------------")


Solution

  • Observation: When you set AscendingKey=False, it does not work correctly.

    This is because in that case, you use (valSign*item[1],-1*item[0]) for sorting. And item[0] is the key, which is a string in your case.

    Multiplying a negative integer with a string seems to always give the empty string:

    >>> -1*"hello"
    ''
    >>> -2*"hello"
    ''
    >>> 1*"hello"
    'hello'
    >>> 2*"hello"
    'hellohello'
    

    The flaw in your logic is thus that you can not invert the string sort order by multiplying them with minus one. Instead, you'd have to sort by their difference to the "largest" value to get descending order.

    In your case, it's probably clearer to write a comparator yourself, as outlined in this answer