Flexable Collating (feedback please)
Ron Adam
rrr at ronadam.com
Wed Oct 18 18:17:57 EDT 2006
This is how I changed it...
(I edited out the test and imports for posting here.)
locale.setlocale(locale.LC_ALL, '') # use current locale settings
class Collate(object):
""" A general purpose and configurable collator class.
"""
options = [ 'CAPS_FIRST', 'NUMERICAL', 'HYPHEN_AS_SPACE',
'UNDERSCORE_AS_SPACE', 'IGNORE_LEADING_WS',
'IGNORE_COMMAS', 'PERIOD_AS_COMMAS' ]
def __init__(self, flags=""):
if flags:
flags = flags.upper().split()
for value in flags:
if value not in self.options:
raise ValueError, 'Invalid option: %s' % value
self.txtable = []
if 'HYPHEN_AS_SPACE' in flags:
self.txtable.append(('-', ' '))
if 'UNDERSCORE_AS_SPACE' in flags:
self.txtable.append(('_', ' '))
if 'PERIOD_AS_COMMAS' in flags:
self.txtable.append(('.', ','))
if 'IGNORE_COMMAS' in flags:
self.txtable.append((',', ''))
self.flags = flags
self.numrex = re.compile(r'([\d\.]*|\D*)', re.LOCALE)
def transform(self, s):
""" Transform a string for collating.
"""
if not self.flags:
return locale.strxfrm(s)
for a, b in self.txtable:
s = s.replace(a, b)
if 'IGNORE_LEADING_WS' in self.flags:
s = s.strip()
if 'CAPS_FIRST' in self.flags:
s = s.swapcase()
if 'NUMERICAL' in self.flags:
slist = self.numrex.split(s)
for i, x in enumerate(slist):
try:
slist[i] = float(x)
except:
slist[i] = locale.strxfrm(x)
return slist
return locale.strxfrm(s)
def __call__(self, a):
""" This allows the Collate class to be used as a sort key.
USE: list.sort(key=Collate(flags))
"""
return self.transform(a)
def collate(slist, flags=[]):
""" Collate list of strings in place.
"""
slist.sort(key=Collate(flags).transform)
def collated(slist, flags=[]):
""" Return a collated list of strings.
"""
return sorted(slist, key=Collate(flags).transform)
More information about the Python-list
mailing list