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

Discussion in 'Python' started by Peter Milliken, Nov 20, 2003.

  1. 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
    Peter Milliken, Nov 20, 2003
    #1
    1. Advertising

  2. 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.



    "Peter Milliken" <> wrote in message
    news:z7avb.541$...
    > 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
    >
    >
    Peter Milliken, Nov 20, 2003
    #2
    1. Advertising

  3. On Fri, 21 Nov 2003 08:13:03 +1100, "Peter Milliken" <> wrote:

    >I am creating a subclass of list that will allow 'ordered' lists via the
    >

    [...]
    You might find the bisect module interesting ;-)

    Regards,
    Bengt Richter
    Bengt Richter, Nov 20, 2003
    #3
  4. > 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)
    Lonnie Princehouse, Nov 21, 2003
    #4
  5. "Peter Milliken" <> wrote in message news:<cgavb.543$>...
    > 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):
    Hannu Kankaanp??, Nov 21, 2003
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. jack
    Replies:
    0
    Views:
    466
  2. Robert Brewer
    Replies:
    1
    Views:
    296
    Peter Milliken
    Nov 20, 2003
  3. David T. Ashley
    Replies:
    22
    Views:
    959
    Malcolm McLean
    Jan 30, 2007
  4. Klaus Schneider
    Replies:
    3
    Views:
    296
  5. AzamSharp
    Replies:
    2
    Views:
    150
Loading...

Share This Page