How do you pass a standard operator such as '<' as a parameter?

P

Peter Milliken

I am creating a subclass of list that will allow 'ordered' lists via the
addition of a new method ('add' for want of a better name :)). Since I want
to make it as generic as possible, I want to pass the comparator function as
an argument at initialisation. It would be used line this:

y = OrderedList([], LessThanFunction)

y.add(9)
y.add(8)
y.add(11)

y

[8,9,11]



So the class definition would look like this:

class OrderedList (list):
def __init__ (self, comparator):
list.__init__(self)
self.ComparisonFunction = comparator

def add (self, element):
"""Add the element into the list in the correct ordered sequence
for
the data type.
"""
# Locate the position in the list and perform the insertion
for i in list(self):
if self.ComparisonFunction(element, i):
list.insert(self, list.index(self, i), element)
break
else:
# element is greater than any current value in the list, so
stick
# it at the end.
list.append(self, element)


For non-standard data types, you would obviously define a '<' function and
then pass it as a parameter at initialisation, but how can you pass one of
the standard operators? i.e. '<'.

For instance, to create an ordered list of integers, I would like to
instantiate new objects using something like this:

y = OrderedList([], <)

However, this results in a syntax error. Is there anyway to pass the '<'
operator itself? I fully realise that you could create a "lessthan"
function, either explicitly or as a lamdba, but my curiousity bump is
itching and I would like to know how to pass one of the standard operators.

Thanks
Peter
 
P

Peter Milliken

Wrote too soon - the obvious answer is not to use a "comparison" function at
all when instantiating the class but rather to just code the "<" in the
class "add" procedure and then make sure the data type that is being used
contains a __lt__ operator :) i.e. the class definition should just be:

class OrderedList (list):
def add (self, element):
"""Add the element into the list in the correct ordered sequence
for
the data type.
"""
# Locate the position in the list and perform the insertion
for i in list(self):
if element < i:
list.insert(self, list.index(self, i), element)
break
else:
# element is greater than any current value in the list, so
stick
# it at the end.
list.append(self, element)

This will work for integers as well as user defined data types that have a
__lt__ function defined.
 
B

Bengt Richter

I am creating a subclass of list that will allow 'ordered' lists via the
[...]
You might find the bisect module interesting ;-)

Regards,
Bengt Richter
 
L

Lonnie Princehouse

For non-standard data types, you would obviously define a '<' function and
then pass it as a parameter at initialisation, but how can you pass one of
the standard operators? i.e. '<'.

Lambda!

my_list = OrderedList([], comparator = lambda a,b: a < b)

You might also consider using the same style of comparator function
that list.sort() uses. This returns 1 for greater than, 0 for equal,
and -1 for less than. Then you could use the builtin cmp function,
and could also sort the OrderedList directly with the comparator:

class OrderedList(list):
def __init__(self, initial=[], comparator=None):
list.__init__(self, initial)
self.ComparisonFunc = comparator
self.sort()

def sort(self, *args):
# use self.ComparisonFunc as default
if len(args):
comparator = args[0]
elif self.ComparisonFunc:
args.append(self.ComparisonFunc)
list.sort(self, *args)
 
H

Hannu Kankaanp??

Peter Milliken said:
Wrote too soon - the obvious answer is not to use a "comparison" function at
all when instantiating the class but rather to just code the "<" in the
class "add" procedure and then make sure the data type that is being used
contains a __lt__ operator :) i.e. the class definition should just be:

Huh? I was certain you wanted to use comparison function to get
flexibility, but by hard-wiring < to the code you'll lose that.
One might want to have the list ordered by some other property,
e.g. from largest element to smallest, or by tuple's second element.
Someone might want to put the same objects in several containers, and
the elements would be sorted differently in each container.

You could just add "less than" as a default behaviour
def __init__ (self, comparator=operator.lt):
 

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,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top