Can I overload the compare (cmp()) function for a Lists ([]) index function?
Hrvoje Niksic
hniksic at xemacs.org
Fri Sep 28 20:12:24 EDT 2007
xkenneth <xkenneth at gmail.com> writes:
> Looking to do something similair. I'm working with alot of timestamps
> and if they're within a couple seconds I need them to be indexed and
> removed from a list.
> Is there any possible way to index with a custom cmp() function?
>
> I assume it would be something like...
>
> list.index(something,mycmp)
The obvious option is reimplementing the functionality of index as an
explicit loop, such as:
def myindex(lst, something, mycmp):
for i, el in enumerate(lst):
if mycmp(el, something) == 0:
return i
raise ValueError("element not in list")
Looping in Python is slower than looping in C, but since you're
calling a Python function per element anyway, the loop overhead might
be negligible.
A more imaginative way is to take advantage of the fact that index
uses the '==' operator to look for the item. You can create an object
whose == operator calls your comparison function and use that object
as the argument to list.index:
class Cmp(object):
def __init__(self, item, cmpfun):
self.item = item
self.cmpfun = cmpfun
def __eq__(self, other):
return self.cmpfun(self.item, other) == 0
# list.index(Cmp(something, mycmp))
For example:
>>> def mycmp(s1, s2):
... return cmp(s1.tolower(), s2.tolower())
>>> ['foo', 'bar', 'baz'].index(Cmp('bar', mycmp))
1
>>> ['foo', 'bar', 'baz'].index(Cmp('Bar', mycmp))
1
>>> ['foo', 'bar', 'baz'].index(Cmp('nosuchelement', mycmp))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: list.index(x): x not in list
The timeit module shows, somewhat surprisingly, that the first method
is ~1.5 times faster, even for larger lists.
More information about the Python-list
mailing list