A.K.M. Adib
A.K.M. Adib

Reputation: 567

Sorting an array of objects based on an instance variable

I'm trying to sort objects in an array based on its' date. For this, I have overridden the sorted method. I'm not allowed to use key with sorted so that's why I'm doing the bubble sort. But previously when I have overridden methods like len I didn't have to add another parameter and for sorted, how would it work? I'm pretty sure I can't do self[i].publication_date. Every time I run the code I get the following error, '<' not supported between instances of 'Article' and 'Article' why doesn't my code address that error?

import datetime


class Article():
    def __init__(self, title: str, author: str, publication_date: datetime.datetime, content: str):
        self.title = title
        self.author = author
        self.publication_date = publication_date
        self.content = content

    def __sorted__(self, x):
        print(x)
        for passnum in range(len(x)-1, 0, -1):
            for i in range(passnum):
                if x[i].publication_date > x[i+1].publication_date:
                    temp = x[i].publication_date
                    x[i].publication_date = x[i+1].publication_date
                    x[i+1].publication_date = temp
        print(x)
        return x


kwargs = {"title": "a", "author": "b", "content": "c"}
articles = [
    Article(
        **kwargs, publication_date=datetime.datetime(2001, 7, 5)),
    Article(
        **kwargs, publication_date=datetime.datetime(1837, 4, 7)),
    Article(
        **kwargs, publication_date=datetime.datetime(2015, 8, 20)),
    Article(
        **kwargs, publication_date=datetime.datetime(1837, 4, 7)),
]
print(articles[1].publication_date)  # prints 1837-04-07 00:00:00
print(sorted(articles))

Upvotes: 1

Views: 354

Answers (2)

Subham
Subham

Reputation: 411

Using dataclasses

import datetime
import dataclasses #pip install dataclasses


@dataclasses.dataclass
class Article:
    title: str
    author: str
    pub_date: datetime.datetime
    content: str
    
    def __lt__(self, other):
        return self.pub_date < other.pub_date
    
kwargs = {"title": "a", "author": "b", "content": "c"}
articles = [
    Article(
        **kwargs, pub_date=datetime.datetime(2001, 7, 5)),
    Article(
        **kwargs, pub_date=datetime.datetime(1837, 4, 7)),
    Article(
        **kwargs, pub_date=datetime.datetime(2015, 8, 20)),
    Article(
        **kwargs, pub_date=datetime.datetime(1837, 4, 7)),
]
print(articles[1].pub_date)
print(sorted(articles))

gives,

1837-04-07 00:00:00
[Article(title='a', author='b', pub_date=datetime.datetime(1837, 4, 7, 0, 0), content='c'), Article(title='a', author='b', pub_date=datetime.datetime(1837, 4, 7, 0, 0), content='c'), Article(title='a', author='b', pub_date=datetime.datetime(2001, 7, 5, 0, 0), content='c'), Article(title='a', author='b', pub_date=datetime.datetime(2015, 8, 20, 0, 0), content='c')]

[Program finished]

Upvotes: 0

kingkupps
kingkupps

Reputation: 3494

You need to implement the __lt__ method only for sorts to work correctly with developer-defined objects.

In this case, your code should become:

import datetime

class Article(object):
    def __init__(self, title: str, author: str, publication_date: datetime.datetime, content: str):
        self.title = title
        self.author = author
        self.publication_date = publication_date
        self.content = content

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

If you want to compare based on more attributes than just publication date, you'll need to add that logic in __lt__.

Upvotes: 4

Related Questions