Sorting a List of Objects by an Attribute of the ObjectsCase-Insensitively

J

Jason

Hi folks--

Basically, I have a pressing need for a combination of 5.2 "Sorting a
List of Strings Case-Insensitively" & 5.3 "Sorting a List of Objects
by an Attribute of the Objects" from the Python Cookbook.

My first guess isn't working:

import operator
def sort_by_attr(seq, attr):
key=operator.attrgetter(attr)
key=str.lower
return sorted(seq, key)

....would much appreciate any guidance!
 
D

David Harrison

Hi folks--

Basically, I have a pressing need for a combination of 5.2 "Sorting a
List of Strings Case-Insensitively" & 5.3 "Sorting a List of Objects
by an Attribute of the Objects" from the Python Cookbook.

My first guess isn't working:

import operator
def sort_by_attr(seq, attr):
key=operator.attrgetter(attr)
key=str.lower
return sorted(seq, key)

...would much appreciate any guidance!

You're probably looking for the built-in function sorted,

e.g.

class Foo:
def __init__(self, value):
self.value = value

def __repr__(self):
return self.value

a = [Foo('c'), Foo('B'), Foo('A')]

print sorted(
a,
cmp=lambda x,y: cmp(x.lower(), y.lower()),
key=lambda x: x.value
)
 
J

Jason

Hi folks--
Basically, I have a pressing need for a combination of 5.2 "Sorting a
List of Strings Case-Insensitively" & 5.3 "Sorting a List of Objects
by an Attribute of the Objects" from the Python Cookbook.
My first guess isn't working:
import operator
def sort_by_attr(seq, attr):
key=operator.attrgetter(attr)
key=str.lower
return sorted(seq, key)
...would much appreciate any guidance!

You're probably looking for the built-in function sorted,

e.g.

class Foo:
def __init__(self, value):
self.value = value

def __repr__(self):
return self.value

a = [Foo('c'), Foo('B'), Foo('A')]

print sorted(
a,
cmp=lambda x,y: cmp(x.lower(), y.lower()),
key=lambda x: x.value
)

Hey-- thanks!

I actually figured out something that works quite nicely since I
posted:

def sort_by_attr_case_insensitive(seq, attr):
return sorted(seq, cmp=lambda x,y: cmp(x.lower(), y.lower()),
key=operator.attrgetter(attr))
 
P

Paddy

Hi folks--

Basically, I have a pressing need for a combination of 5.2 "Sorting a
List of Strings Case-Insensitively" & 5.3 "Sorting a List of Objects
by an Attribute of the Objects" from the Python Cookbook.

My first guess isn't working:

import operator
def sort_by_attr(seq, attr):
key=operator.attrgetter(attr)
key=str.lower
return sorted(seq, key)

...would much appreciate any guidance!

HiJason,
Try key= lambda x: x.attr.lower()
The above should calculate the key only once for the items to be
sorted rather than using cmp which calculates more than that.

- Paddy.
 
P

Peter Otten

Paddy said:
HiJason,
Try key= lambda x: x.attr.lower()
The above should calculate the key only once for the items to be
sorted rather than using cmp which calculates more than that.

A key func is indeed preferable over cmp. Here is a working example:
.... def __init__(self, name, value):
.... self.name = name
.... self.value = value
.... def __repr__(self):
.... return "%s|%s" % (self.name, self.value)
....
items = [A("a", "z"), A("C", "Y"), A("b", "x")]
items [a|z, C|Y, b|x]
def sorted_by_attr_icase(items, attrname):
.... get = operator.attrgetter(attrname)
.... return sorted(items, key=lambda item: get(item).lower())
....
sorted_by_attr_icase(items, "name") [a|z, b|x, C|Y]
sorted_by_attr_icase(items, "value")
[b|x, C|Y, a|z]

Peter
 
J

Jason

Thanks so much everyone! That works great, & (presumably) is way
faster than the way I was doing it--
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top