2012-07-08 20 views
6

¿Cómo puedo decirle a difflib.get_close_matches() que ignore el caso? Tengo un diccionario que tiene un formato definido que incluye mayúsculas. Sin embargo, la cadena de prueba podría tener mayúsculas completas o sin mayúsculas, y estas deberían ser equivalentes. Sin embargo, los resultados deben estar debidamente escritos en mayúscula, por lo que no puedo usar un diccionario modificado.Ignorar el caso con difflib.get_close_matches()

import difflib 

names = ['Acacia koa A.Gray var. latifolia (Benth.) H.St.John', 
    'Acacia koa A.Gray var. waianaeensis H.St.John', 
    'Acacia koaia Hillebr.', 
    'Acacia kochii W.Fitzg. ex Ewart & Jean White', 
    'Acacia kochii W.Fitzg.'] 
s = 'Acacia kochi W.Fitzg.' 

# base case: proper capitalisation 
print(difflib.get_close_matches(s,names,1,0.9)) 

# this should be equivalent from the perspective of my program 
print(difflib.get_close_matches(s.upper(),names,1,0.9)) 

# this won't work because of the dictionary formatting 
print(difflib.get_close_matches(s.upper().capitalize(),names,1,0.9)) 

Salida:

['Acacia kochii W.Fitzg.'] 
[] 
[] 

código de trabajo:

Sobre la base de la respuesta de Hugh Bothwell, he modificado el código de la siguiente manera para obtener una solución de trabajo (que también debería funcionar cuando más que se devuelve un resultado):

import difflib 

names = ['Acacia koa A.Gray var. latifolia (Benth.) H.St.John', 
    'Acacia koa A.Gray var. waianaeensis H.St.John', 
    'Acacia koaia Hillebr.', 
    'Acacia kochii W.Fitzg. ex Ewart & Jean White', 
    'Acacia kochii W.Fitzg.'] 
test = {n.lower():n for n in names}  
s1 = 'Acacia kochi W.Fitzg.' # base case 
s2 = 'ACACIA KOCHI W.FITZG.' # test case 

results = [test[r] for r in difflib.get_close_matches(s1.lower(),test,1,0.9)] 
results += [test[r] for r in difflib.get_close_matches(s2.lower(),test,1,0.9)] 
print results 

Salida:

['Acacia kochii W.Fitzg.', 'Acacia kochii W.Fitzg.'] 
+0

Perdón por reiniciar una publicación anterior, pero esto me pareció interesante. Para el producto de búsqueda final, estoy leyendo el código y parece que no necesitaría la lista s1 y primeros resultados. ¿Es eso correcto? Parece que el algoritmo produciría el resultado que quería sin esas líneas. –

+0

@TylerRussell eso es correcto. El objetivo era verificar que la capitalización del término de búsqueda no influyera en el resultado. El hecho de que buscar con s1 y buscar con s2 produjo el mismo resultado mostró que el algoritmo funcionó. En general, solo usarías un término de búsqueda. – rudivonstaden

Respuesta

7

no veo ninguna manera rápida de hacer difflib hacer la comparación entre mayúsculas y minúsculas.

La solución rápida y sucia-parece ser

  • crea una función que convierte la cadena a alguna forma canónica (por ejemplo: mayúsculas, espacio sencillo, no puntuacion)

  • use esa función para hacer un dict de {cadena canónica: cadena original} y una lista de [cadena canónica]

  • ejecute .get_close_matches contra la lista de cadenas canónicas, luego tape los resultados a través del dict para obtener el origen al cuerdas atrás

+0

Gracias. No es elegante, pero funciona! – rudivonstaden

Cuestiones relacionadas