Not sure why this was so hard for me to use the sorted() method this morning.
I’m playing with the FriendFeed API, I wanted to retrieve the entries of a FriendFeed room, and then sort the returned entries by the number of comments…
Getting the latest 30 entries is a simple HTTP call. FriendFeed returns a json structure which is nicely parsed with simplejson (soon to be part of the standard python library).
import simplejson
import urllib2
r = urllib2.urlopen('http://friendfeed.com/api/feed/room/science21')
json = simplejson.loads(r.read())
# I just want to look at the entries in the room
e = json['entries']
I want to sort the entries by the number of comments. In other words, I want to use the number of comments as a sort key. Luckly, Python’s sorted() method has a key attribute, which takes a callable that returns a single value to be used as a key. We use the operator module in order to generate the sorting key method:
ln = lambda x: len(operator.getitem(x,'comments'))
esorted = sorted(e,key=ln,reverse=True)</code>
for i in esorted:
print i['title'].encode('utf-8'), len(i['comments'])
That took me all morning to get, which shows some of my Python programming limitations. My first attempt, I tried this:
In [94]: es = sorted(e, key=len(operator.itemgetter('comments')))
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/home/fitzgeraldsteele/<ipython console> in <module>()
TypeError: object of type 'operator.itemgetter' has no len()
Now I recall that an object must have a .__len__() method in order to work with len(). But operator.itemgetter() returns a function, not an object with a .__len__(), hence the TypeError exceptin I got.
Then I tried this:
esorted = sorted(e, key=lambda x: len(operator.getitem(x,'comments')))
Which is very similar to the solution I ended up with, but this one returns the list in different order. I’m not sure why yet. Update: Duh…we get a different order because the first one has reverse=True, and the second one doesn’t.