comparing lists
jepler at unpythonic.net
jepler at unpythonic.net
Wed May 8 19:17:04 EDT 2002
def compare_with_dict(l, m):
d = {}
if len(l) != len(m): return 0 # Cannot be equal (?)
for i in l: d[i.lower()] = 0
for i in m:
if i.lower() not in d: return 0 # Proven unequal
return 1
Setting a key in a dict and checking for a key in dict ('d.has_key(k)' in
older versions of Python) are supposed to be constant-time operations, so
this is O(len(l) + len(m)) to run.
Your versions either use sort (O(n lg n)) or 'in' with lists (O(n^2)),
so this one should perform better than the original.
However, you might want to use the dict-representation all the time. It'd
save you the cost of the copy. If the original case is sometimes
important, you might store the key as the lowercase version with the value
as the original case (eg l['studlycaps'] == 'StUdLyCaPs')
>>> t = CaseInsensitiveSet()
>>> u = CaseInsensitiveSet()
>>> print t == u
1
>>> t.add('a')
>>> u.add('B')
>>> print t == u
0
>>> t.add('b')
>>> u.add('a')
>>> print t, `u`, u['b'], u['B']
<Set a b> <Set 'a' 'b'> B B
>>> print t == u
1
>>> u.remove('b')
>>> print t == u
0
>>> t.remove('b')
>>> print t == u
1
Here's an implementation for 2.2 (tested against 2.3a0 CVS):
class CaseInsensitiveSet(dict):
def __setitem__(self, item, value):
item = item.lower()
super(CaseInsensitiveSet, self).__setitem__(item, value)
def __getitem__(self, item):
item = item.lower()
return super(CaseInsensitiveSet, self).__getitem__(item)
def add(self, item):
self[item] = item
def remove(self, item):
del self[item]
def __eq__(self, other):
for k in self:
if not k in other: return 0
return 1
# for sk, ok in zip(self, other):
# if sk != ok: return 0
# return
def __str__(self):
return "<Set %s>" % " ".join(self)
def __repr__(self):
return "<Set %s>" % " ".join(map(repr, self))
More information about the Python-list
mailing list