Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial
Denny Ho
4,472 Pointsfunctional python: item vs attribute
Hi, In the Function Python Workhorses: Sorting video, there's a part at the end where Kenneth Love uses both itemgetter and attrgetter. I'm a bit confused as to why/how the two are used differently. Why is publish_date an item to be referenced while number_of_pages is an object attribute? Looking at the json file, it seems as though both publish_date and number_of_pages are written/stored similarly and should be called the same way. I tried flipping the keys (used attrgetter for publish_date and itemgetter for number_of_pages) but it didn't work. Could someone help me to understand why?
import json
from operator import attrgetter, itemgetter
class Book:
def __init__(self, **kwargs):
for k, v in kwargs.items():
setattr(self, k, v)
def __str__(self):
return self.title
def __repr__(self):
return str(self)
def get_books(filename, raw=False):
try:
data = json.load(open(filename))
except FileNotFoundError:
return []
else:
if raw:
return data['books']
return [Book(**book) for book in data['books']]
BOOKS = get_books('books.json')
RAW_BOOKS = get_books('books.json', raw=True)
# pub_sort = sorted(RAW_BOOKS, key=itemgetter('publish_date'))
# print(pub_sort[0]['publish_date'], pub_sort[-1]['publish_date'])
pages_sort = sorted(BOOKS, key=attrgetter('number_of_pages'))
print(pages_sort[0].number_of_pages, pages_sort[-1].number_of_pages)
#important_list = [5, 3, 1, 2, 4]
#important_list.sort() # Bad idea, sorts list in place
# sorted(important_list) # Sorts a copy of the list
here's a couple of examples from the json file
{ "books" : [ { "number_of_pages" : 849,
"price" : 13.550000000000001,
"publish_date" : 2011,
"subjects" : [ "Time travel",
"Assassination"
],
"title" : "11/22/63"
},
{ "number_of_pages" : 732,
"price" : 7.9900000000000002,
"publish_date" : 1999,
"subjects" : [ "Authors",
"Custody of children",
"Grandfathers",
"Haunted houses",
"Novelists",
"Trials (Custody of children)",
"Widowers",
"Widows",
"Writer's block"
],
"title" : "Bag of bones"
},
2 Answers

Chris Freeman
Treehouse Moderator 68,468 PointsThe specifically difference between using attrgetter
and itemgetter
is the target object. Since BOOKS is an object with attributes, and RAW_BOOKS is a "container" (list, dict, set) filled with items, the choice becomes clearer.
Denny Ho
4,472 Pointsbecause there's a difference between BOOKS and RAW_BOOKS. just caught that. sorry.