[pyar] Problema interesante: el anti-string
Roberto Alsina
ralsina en netmanagers.com.ar
Jue Ago 5 10:04:14 ART 2010
On Thursday 05 August 2010 09:52:31 John Rowland Lenton wrote:
> On Wed, Aug 04, 2010 at 04:03:02PM -0300, Roberto Alsina wrote:
> > Forma más fácil del problema:
> >
> > Dado un string S, crear una funcion f tal que S1>S2 => f(S1) < f(S2)
> >
> > Ahí creo que es más claro :-)
>
> creo que ya tenés una solución, pero tengo otra (o será la misma? :)
>
> y ambas usan el hecho de que python no ordena por colación (que
> depende del locale) sino por el ord() del unicode.
>
> Como siempre, tratándose de unicode, tengo que meter la aclaración de
> que si estás comparando cosas, lo primero que tenés que hacer es
> normalizar. En particular, me gusta la función de normalización que
> hice para el plugin de Ubuntu One para Rhythmbox,
>
> SCRUBBING_RE = re.compile(r"[\W\s]+", re.UNICODE)
> CLEANING_RE = re.compile(r"\s+", re.UNICODE)
>
> def normalize(a):
> """Normalize the given string, to increase the chances of a
> match""" # rule #0 of unicode mangling: first, normalize
> na = unicodedata.normalize('NFKD', a)
> # then, strip everything that's not alphanumeric
> na = re.sub(SCRUBBING_RE, "", na)
> # \w leaves _s
> na = na.replace("_", " ")
> # then, unify spaces
> na = re.sub(CLEANING_RE, " ", na).strip()
> # finally, lowercase
> na = na.lower()
> # if there's anything left, go with that, otherwise rollback
> return na if na else a
>
> (© 2010 canonical, licenciado bajo LGPLv3, autor el que suscribe)
>
> pero claro esto es bastante caro, y lo puedo hacer porque sé que no
> voy a tener demasiadas cosas para normalizar. Si tuviera muchas,
> habría hecho solamente el primer paso (normalización a NFKD); las
> normalizaciones que descomponen (NFKD y NFD) son buenísimas para
> nosotros, porque ordenan árbol después de az y antes de ba (en vez de
> después de zz). Las normalizaciones K llevan ¹ a 1 y º a o, que
> también es lo que queremos para ordenar.
>
>
> Bueno, habiendo dicho eso, una forma de hacer lo que querés sería:
>
> def f(s):
> array.array('l', [-ord(i) for i in s])
>
> y otra forma sería:
>
> def f(s):
> return "".join(unichr(0x10ffff-ord(i)) for i in s)
>
> la primera usa menos memoria (medida con sys.getsizeof). No he medido
> cuál es más rápida. 0x10ffff es el ord más alto de un unicode válido
> en pythones más o menos nuevos (no sé cuándo empezó a ser así, pero
> hace bastante) (y todavía podés compilar python para que sea más
> chico, pero nadie lo hace que yo sepa).
Listo, me convenciste :-)
More information about the pyar
mailing list