0

In Python, is there a function that classifies and orders an array of objects by an attribute?

Example:

class Book:
    """A Book class"""
    def __init__(self,name,author,year):
        self.name = name
        self.author = author
        self.year = year

hp1 = Book("Harry Potter and the Philosopher's stone","J.k Rowling",1997)
hp2 = Book("Harry Potter and the chamber of secretse","J.k Rowling",1998)
hp3 = Book("Harry Potter and the Prisioner of Azkaban","J.k Rowling",1999)

#asoiaf stands for A Song of Ice and Fire
asoiaf1 = Book("A Game of Thrones","George R.R Martin",1996)
asoiaf2 = Book("A Clash of Kings","George R.R Martin",1998)

hg1 = Book("The Hunger Games","Suzanne Collins",2008)
hg2 = Book("Catching Fire","Suzanne Collins",2009)
hg3 = Book("Mockingjaye","Suzanne Collins",2010);

books = [hp3,asoiaf1,hp1,hg1,hg2,hp2,asoiaf2,hg3]
#disordered on purpose

organized_by_autor = magic_organize_function(books,"author")

Does the magic_organize_function exist? Otherwise, what would it be?

Mike Müller
  • 82,630
  • 20
  • 166
  • 161
  • So do you want to group-by and sort by author? – wkl Dec 20 '16 at 21:02
  • 3
    The `sorted()` function in Python takes a `key` parameter. It is used to specify _how_ you want your list sorted. In your case you want to sort by the `author` attribute of each element in the list `books`: `organized_by_autor = sorted(books, lambda book: book.author)` – Christian Dean Dec 20 '16 at 21:02
  • FWIW the `;` are superfluous. They don't do anything. – Wayne Werner Dec 20 '16 at 21:04
  • If the linked question doesn't solve your problem, let me know. – Wayne Werner Dec 20 '16 at 21:04
  • If the duplicate that @WayneWerner linked to is still not clear, I suggest taking at look at [this](http://stackoverflow.com/questions/4010322/sort-a-list-of-class-instances-python) post. – Christian Dean Dec 20 '16 at 21:07
  • @WayneWerner I was gonna suggest he use groupby after sorting for that 'classification' he asked, but now I'm gonna go to sleep, so if you reopen, help him out – themistoklik Dec 20 '16 at 21:09
  • @WayneWerner the linked question wasn't what I was looking for, I was looking for the itertools.groupby function, but thank you anyways. – Eduardo Andrés Castillo Perera Dec 20 '16 at 22:04
  • @EduardoAndrésCastilloPerera I've re-opened your question - you should accept Mike's answer by clicking the checkmark to the left of the answer, since it answers your question. – Wayne Werner Dec 21 '16 at 05:53

1 Answers1

1

Sorting by author is one way:

sorted_by_author = sorted(books, key=lambda x: x.author)
for book in sorted_by_author:
    print(book.author)

Output:

George R.R Martin
George R.R Martin
J.k Rowling
J.k Rowling
J.k Rowling
Suzanne Collins
Suzanne Collins
Suzanne Collins

You can also nicely group by author using itertools.groupby:

from itertools import groupby

organized_by_author = groupby(sorted_by_author, key=lambda x: x.author)

for author, book_from_author in organized_by_author:
    print(author)
    for book in book_from_author:
        print('    ', book.name)

Output:

George R.R Martin
     A Game of Thrones
     A Clash of Kings
J.k Rowling
     Harry Potter and the Prisioner of Azkaban
     Harry Potter and the Philosopher's stone
     Harry Potter and the chamber of secretse
Suzanne Collins
     The Hunger Games
     Catching Fire
     Mockingjaye

Note: You need to feed groupby the sorted sorted_by_author.

Mike Müller
  • 82,630
  • 20
  • 166
  • 161