user10614103
user10614103

Reputation:

Sorting with a class made by me where the data is stored as a list

I have a class in the form:

class piece:
    dim = [0,0]
    area = 0
    def __init__(self, dim):
        self.dim = dim
        self.area = dim[0] *dim[1]
    def p(self):
        print('length: ',self.dim[0])
        print('width: ', self.dim[1])
        print('area: ', self.area)
    def rotate(self):
        temp = self.dim[0]
        self.dim[0] = self.dim[1]
        self.dim[1] = temp

When I append these objects in a list and now I am trying to use the sort function in hopes it will sort based on the area. But it didn't work. So should I create a list of my own inside the new class and also incorporate a sort function? Also the only sort I know how to implement is bubble and binary is there something more efficient?

Upvotes: 1

Views: 48

Answers (2)

Andrej Kesely
Andrej Kesely

Reputation: 195438

Consider using the functools.total_ordering class decorator to do the work (you need to define just __eq__ and one for example __lt__ and the class decorator supplies the rest):

from functools import total_ordering


@total_ordering
class piece:
    def __init__(self, dim):
        self.dim = dim
        self.area = dim[0] * dim[1]

    def p(self):
        print("length: ", self.dim[0])
        print("width: ", self.dim[1])
        print("area: ", self.area)

    def rotate(self):
        temp = self.dim[0]
        self.dim[0] = self.dim[1]
        self.dim[1] = temp

    def __eq__(self, other):
        return self.area == other.area

    def __lt__(self, other):
        return self.area < other.area

    def __repr__(self):
        return "piece({})".format(self.dim)

Example:

from random import randint

lst = [piece((randint(1, 10), randint(1, 10))) for _ in range(5)]

print("Before sorted:", lst)

lst.sort()
print("After sorted:", lst)

Prints:

Before sorted: [piece((5, 4)), piece((7, 4)), piece((2, 9)), piece((1, 7)), piece((7, 8))]
After sorted: [piece((1, 7)), piece((2, 9)), piece((5, 4)), piece((7, 4)), piece((7, 8))]

Upvotes: 1

Chrispresso
Chrispresso

Reputation: 4071

You need a way to compare objects. If you want to sort by area then your goal is to have one area be compared to another:

In [48]: class Piece:
    ...:     def __init__(self, dim):
    ...:         self._dim = dim
    ...:         self.area = dim[0]*dim[1]
    ...:     def __lt__(self, other):
    ...:         return self.area < other.area
    ...:     def __repr__(self):
    ...:         return str(self._dim)
    ...:

In [49]: p1 = Piece((5,5))

In [50]: p2 = Piece((2,3))

In [51]: p3 = Piece((3,2))

In [52]: sorted([p1, p2, p3])
Out[52]: [(2, 3), (3, 2), (5, 5)]

Upvotes: 1

Related Questions