Search code examples
pythonsortingcurrency

sorting value pairs with one pair being in dollar format in python


so I have a list like this.

items = [('30-Apr-2018', '$0.14'), ('30-Apr-2018', '$1,534.77'), ('29-Apr-2018', '-$7.34')]

I tried using these two commands to sort it which I think perform the same sorting

items = sorted(items, key=lambda x: x[1])
items = sorted(items,key=itemgetter(1))

But they keep getting out of order. It looks like some sorting is done? But not correctly for some reason, which I suspect is due to the format of the second element in the list pair. Any suggestions on how to sort this? The only option that I see is to convert the dollar value to decimal then try sorting again, and maybe adding the dollar sign back, but maybe someone else would have a better solution.

The full list is here. before sort = [('30-Apr-2018', '$0.14'), ('30-Apr-2018', '$101.65'), ('30-Apr-2018', '$1,534.77'), ('29-Apr-2018', '-$37.78'), ('29-Apr-2018', '$6.31'), ('29-Apr-2018', '-$4.76'), ('29-Apr-2018', '-$39.55'), ('28-Apr-2018', '-$664.78'), ('28-Apr-2018', '-$142.25'), ('28-Apr-2018', '-$9.12'), ('27-Apr-2018', '-$7.34'), ('27-Apr-2018', '-$7.34'), ('26-Apr-2018', '-$7.34'), ('26-Apr-2018', '-$13.23'), ('25-Apr-2018', '-$7.34'), ('25-Apr-2018', '-$2.09'), ('24-Apr-2018', '-$27.27'), ('24-Apr-2018', '-$9.96'), ('24-Apr-2018', '-$110.00'), ('23-Apr-2018', '-$7.34'), ('22-Apr-2018', '-$87.02'), ('22-Apr-2018', '-$5.41'), ('22-Apr-2018', '-$21.11'), ('21-Apr-2018', '-$12.69'), ('21-Apr-2018', '-$6.75'), ('21-Apr-2018', '-$500.00'), ('21-Apr-2018', '-$15.67'), ('20-Apr-2018', '-$41.74'), ('20-Apr-2018', '-$20.47'), ('20-Apr-2018', '$31.60'), ('19-Apr-2018', '-$7.34'), ('19-Apr-2018', '-$2.09'), ('19-Apr-2018', '-$5.24'), ('19-Apr-2018', '-$22.70'), ('18-Apr-2018', '-$7.34'), ('17-Apr-2018', '-$7.34'), ('17-Apr-2018', '-$4.99'), ('17-Apr-2018', '-$7.34'), ('16-Apr-2018', '-$7.33'), ('16-Apr-2018', '-$59.00'), ('15-Apr-2018', '-$42.75'), ('14-Apr-2018', '-$9.43'), ('13-Apr-2018', '$1,545.79'), ('12-Apr-2018', '-$7.34'), ('12-Apr-2018', '-$11.63'), ('12-Apr-2018', '-$14.44'), ('11-Apr-2018', '-$81.31'), ('10-Apr-2018', '-$79.74'), ('10-Apr-2018', '-$7.34'), ('10-Apr-2018', '-$11.11'), ('09-Apr-2018', '-$7.34'), ('07-Apr-2018', '-$72.42'), ('06-Apr-2018', '-$3.01'), ('06-Apr-2018', '-$7.34'), ('05-Apr-2018', '-$7.34'), ('05-Apr-2018', '-$9.20'), ('04-Apr-2018', '-$7.34'), ('03-Apr-2018', '-$7.34'), ('03-Apr-2018', '-$460.00'), ('03-Apr-2018', '-$7.34'), ('02-Apr-2018', '-$7.34'), ('02-Apr-2018', '$289.04'), ('01-Apr-2018', '-$6.30'), ('01-Apr-2018', '-$7.50'), ('01-Apr-2018', '-$13.28')]

after sort = [('30-Apr-2018', '$0.14'), ('30-Apr-2018', '$1,534.77'), ('13-Apr-2018', '$1,545.79'), ('30-Apr-2018', '$101.65'), ('02-Apr-2018', '$289.04'), ('20-Apr-2018', '$31.60'), ('29-Apr-2018', '$6.31'), ('10-Apr-2018', '-$11.11'), ('12-Apr-2018', '-$11.63'), ('24-Apr-2018', '-$110.00'), ('21-Apr-2018', '-$12.69'), ('26-Apr-2018', '-$13.23'), ('01-Apr-2018', '-$13.28'), ('12-Apr-2018', '-$14.44'), ('28-Apr-2018', '-$142.25'), ('21-Apr-2018', '-$15.67'), ('25-Apr-2018', '-$2.09'), ('19-Apr-2018', '-$2.09'), ('20-Apr-2018', '-$20.47'), ('22-Apr-2018', '-$21.11'), ('19-Apr-2018', '-$22.70'), ('24-Apr-2018', '-$27.27'), ('06-Apr-2018', '-$3.01'), ('29-Apr-2018', '-$37.78'), ('29-Apr-2018', '-$39.55'), ('29-Apr-2018', '-$4.76'), ('17-Apr-2018', '-$4.99'), ('20-Apr-2018', '-$41.74'), ('15-Apr-2018', '-$42.75'), ('03-Apr-2018', '-$460.00'), ('19-Apr-2018', '-$5.24'), ('22-Apr-2018', '-$5.41'), ('21-Apr-2018', '-$500.00'), ('16-Apr-2018', '-$59.00'), ('01-Apr-2018', '-$6.30'), ('21-Apr-2018', '-$6.75'), ('28-Apr-2018', '-$664.78'), ('16-Apr-2018', '-$7.33'), ('27-Apr-2018', '-$7.34'), ('27-Apr-2018', '-$7.34'), ('26-Apr-2018', '-$7.34'), ('25-Apr-2018', '-$7.34'), ('23-Apr-2018', '-$7.34'), ('19-Apr-2018', '-$7.34'), ('18-Apr-2018', '-$7.34'), ('17-Apr-2018', '-$7.34'), ('17-Apr-2018', '-$7.34'), ('12-Apr-2018', '-$7.34'), ('10-Apr-2018', '-$7.34'), ('09-Apr-2018', '-$7.34'), ('06-Apr-2018', '-$7.34'), ('05-Apr-2018', '-$7.34'), ('04-Apr-2018', '-$7.34'), ('03-Apr-2018', '-$7.34'), ('03-Apr-2018', '-$7.34'), ('02-Apr-2018', '-$7.34'), ('01-Apr-2018', '-$7.50'), ('07-Apr-2018', '-$72.42'), ('10-Apr-2018', '-$79.74'), ('11-Apr-2018', '-$81.31'), ('22-Apr-2018', '-$87.02'), ('28-Apr-2018', '-$9.12'), ('05-Apr-2018', '-$9.20'), ('14-Apr-2018', '-$9.43'), ('24-Apr-2018', '-$9.96')]


Solution

  • In order to sort your price, you first need to convert them in a numeric format (float or integer). So to convert your string, you need the following step:

    1. Remove all the ","
    2. Check if the number is negative (start with "-")
    3. Convert to digits to float
    4. Convert to int

    You can use the following code:

    def convert(string):
        string = string.replace(",","")
        num_val = 0.0
        if string[0]=="-":
            num_val = -float(string[2:])
        else:
            num_val = float(string[1:])
        # If you want integer value in cents
        # return int(round(num_val*100.0))
        return num_value
    
    items = [(d, convert(p)) for (d,p) in items]
    

    The result you get can be explained by the fact that when sorting string, you do it character by character and "-" > "$" so all the negative number are at the end and sorted in lexicographical order.