Posts Tagged sorting
Python tip: Sorting lists by its contents
Posted by fitzgeraldsteele in python, scholarlycommunication on September 11, 2008
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.