On 12/13/11 09:48, tinn...@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



--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to