Using methodcaller in a list sort - any examples anywhere?

Tim Chase python.list at tim.thechases.com
Tue Dec 13 11:08:06 EST 2011


On 12/13/11 09:48, tinnews at isbd.co.uk wrote:
> I want to sort a list of 'things' (they're fairly complex objects) by
> the contents of one of the fields I can extract from the 'things'
> using a Python function.
>
> So I have a list L which is a list of objects of some sort.  I can
> output the contents of a field in the list as follows:-
>
>      for k in L:
>          print k.get_property('family-name')
>
> How can I sort the list first?  As I said it seems like a methodcaller
> is the answer but I don't see how.  I want to sort the list of objects
> not just produce a sorted list of names.

You want either sorted(..., key=...) to sort and return a copy 
(leaving the original unmodified) or .sort(key=...) to sort the 
list in-place:

   class MyObj(object):
     def __init__(self, fn): self.fn = fn
     def get_property(self, s): return "%s: %s" % (s, self.fn)
     def __str__(self): return self.fn
     __repr__ = __str__

   source = [
     MyObj("Doug"),
     MyObj("Carol"),
     MyObj("Bill"),
     MyObj("Adam"),
     ]

   print "Unsorted source before:"
   print repr(source)
   print "Using a lambda:"
   print repr(sorted(source,
     key=lambda mo: mo.get_property("family-name")))

   print "Using methodcaller:"
   from operator import methodcaller
   print repr(sorted(source,
     key=methodcaller("get_property", "family-name")))

   print "Source still unsorted after:"
   print repr(source)
   source.sort(key=lambda mo: mo.get_property("family-name"))
   print "Source now sorted:"
   print repr(source)

yields the following:

   Unsorted source before:
   [Doug, Carol, Bill, Adam]
   Using a lambda:
   [Adam, Bill, Carol, Doug]
   Using methodcaller:
   [Adam, Bill, Carol, Doug]
   Source still unsorted after:
   [Doug, Carol, Bill, Adam]
   Source now sorted:
   [Adam, Bill, Carol, Doug]

I'm partial to the lambda version over the methodcaller version 
unless there's a reason to dynamically get the method-name as a 
string.  But that's just a personal preference.

-tkc






More information about the Python-list mailing list