Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #17142 > unrolled thread
| Started by | tinnews@isbd.co.uk |
|---|---|
| First post | 2011-12-13 15:48 +0000 |
| Last post | 2011-12-13 10:08 -0600 |
| Articles | 4 — 3 participants |
Back to article view | Back to comp.lang.python
Using methodcaller in a list sort - any examples anywhere? tinnews@isbd.co.uk - 2011-12-13 15:48 +0000
Re: Using methodcaller in a list sort - any examples anywhere? Peter Otten <__peter__@web.de> - 2011-12-13 17:13 +0100
Re: Using methodcaller in a list sort - any examples anywhere? tinnews@isbd.co.uk - 2011-12-13 16:48 +0000
Re: Using methodcaller in a list sort - any examples anywhere? Tim Chase <python.list@tim.thechases.com> - 2011-12-13 10:08 -0600
| From | tinnews@isbd.co.uk |
|---|---|
| Date | 2011-12-13 15:48 +0000 |
| Subject | Using methodcaller in a list sort - any examples anywhere? |
| Message-ID | <hm8kr8-uge.ln1@chris.zbmc.eu> |
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.
--
Chris Green
[toc] | [next] | [standalone]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2011-12-13 17:13 +0100 |
| Message-ID | <mailman.3602.1323792823.27778.python-list@python.org> |
| In reply to | #17142 |
tinnews@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.
The most obvious way is to use a custom function
def get_family_name(obj):
return obj.get_property("family-name")
L.sort(key=get_family_name)
However, since you already know about methodcaller
"""
class methodcaller(builtins.object)
| methodcaller(name, ...) --> methodcaller object
|
| Return a callable object that calls the given method on its operand.
| After, f = methodcaller('name'), the call f(r) returns r.name().
| After, g = methodcaller('name', 'date', foo=1), the call g(r) returns
| r.name('date', foo=1).
""""
L.sort(key=methodcaller("get_property", "family-name"))
[toc] | [prev] | [next] | [standalone]
| From | tinnews@isbd.co.uk |
|---|---|
| Date | 2011-12-13 16:48 +0000 |
| Message-ID | <j8ckr8-b84.ln1@chris.zbmc.eu> |
| In reply to | #17145 |
Peter Otten <__peter__@web.de> wrote:
> tinnews@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.
>
> The most obvious way is to use a custom function
>
> def get_family_name(obj):
> return obj.get_property("family-name")
> L.sort(key=get_family_name)
>
> However, since you already know about methodcaller
>
> """
> class methodcaller(builtins.object)
> | methodcaller(name, ...) --> methodcaller object
> |
> | Return a callable object that calls the given method on its operand.
> | After, f = methodcaller('name'), the call f(r) returns r.name().
> | After, g = methodcaller('name', 'date', foo=1), the call g(r) returns
> | r.name('date', foo=1).
> """"
>
> L.sort(key=methodcaller("get_property", "family-name"))
>
OK, thanks, just what I wanted.
--
Chris Green
[toc] | [prev] | [next] | [standalone]
| From | Tim Chase <python.list@tim.thechases.com> |
|---|---|
| Date | 2011-12-13 10:08 -0600 |
| Message-ID | <mailman.3607.1323796837.27778.python-list@python.org> |
| In reply to | #17142 |
On 12/13/11 09:48, tinnews@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
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web