I'm scraping a website for certain values like name, price, stock and rating and have been using the functions
my_products.sort(key = lambda x: x.return_name())
my_products.sort(key = lambda x: x.return_price())
my_products.sort(key = lambda x: x.return_rating())
my_products.sort(key = lambda x: x.return_stock())
to sort them. It all works fine and dandy, except it doesn't sort the price numerically, it lists them like 1000, 1500, 20, 200, 2000, 2500. Which isn't exactly what I'm looking for. How can I change this sorting behavior?
The class for each product:
class Product():
__title = ""
__price = ""
__rating =""
__stock = ""
def __init__(self,title, price, rating, stock):
self.__title = title
self.__price = price
self.__rating = rating
self.__stock = stock
def toString(self):
return "Title: {}\nPrice: {}\nRating: {}\nStock: {}\n".format( self.__title,
self.__price,
self.__rating,
self.__stock)
def return_price(self):
return self.__price
def return_name(self):
return self.__title
def return_rating(self):
return self.__rating
def return_stock(self):
return self.__stock
As you write it in your class, price is a string, then all prices will be compared like strings.
You have two options:
my_products.sort(key = lambda x: float(x.return_price())).int() or float()Declare price directly as a numeric (and don't change the sorting syntax):
class Product():
__title = ""
__price = np.nan
__rating =""
__stock = ""
def __init__(self,title, price, rating, stock):
self.__title = title
#---
self.__price = price#if price is a numeric input
#or convert to the right type if price is a string input
self.__price = float(price)
#---
self.__rating = rating
self.__stock = stock
In my opinion I would use the option 2 to stay coherent with the meaning of the values. Note that you should rewrite your functions accordingly to new types.
Maybe you could do the same with your ratings / stocks (if it is numeric too).
EDIT - String comparison and sorting
To compare string python convert characters into their ordinal equivalent then check int from left to right. So '1000' is lower than '20', see below:
print('1000 : %d' %sum(ord(i) for i in '1000'))
print('1500 : %d' %sum(ord(i) for i in '1500'))
print('20 : %d' %sum(ord(i) for i in '20'))
#output
1000 : 193
1500 : 198
20 : 98
Just convert strings to numbers (e.g. int or float) in your key function:
my_products.sort(key = lambda x: float(x.return_price()))
You could also update the method so that it returns a number in the first place:
def return_price(self):
return float(self.__price)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With