2011-12-15 20 views
5

Tengo que escribir una función que toma una cadena como argumento y comparar esta cadena con otras dos cadenas y devolver la cadena más similar y el número de diferencias.comparación de dos cadenas y devolver la más similar

def func("LUMB"): 
    lst=["JIBM", "NUNE", "NUMB"] 
should return: 
("NUMB",1) 

que he intentado:

def f(word): 
    lst=["JIBM", "NUNE", "NUMB"] 
    for i in lst: 
     d=k(word, lst) 
     return differences 
     for n in d: 
      print min(sum(n)) 

donde:

def k(word1, word2): 
    L=[] 
    for w in range(len(word1)): 
     if word1[w] != word2[w]: 
      L.append(1) 
     else: 
      L.append(0) 
    return L 

modo que me sale una lista de, por ejemplo, [1,0,0,0] si palabra1 = "NUMB "y word2 =" LUMB "

+3

¿Has visto [Algoritmo de diferencia de texto] (http://stackoverflow.com/questions/145607/text-difference-algorithm) y [Módulos de Good Python para la comparación de cadenas difusas] (http://stackoverflow.com/questions)/682367/good-python-modules-for-fuzzy-string-comparison) – Chris

+0

También hay un número de respuestas disponibles en este enlace http://stackoverflow.com/questions/682367/good-python-modules-for-fuzzy -string-comparison –

+0

En el sitio hay una publicación similar. Obtendrá algunas respuestas más valiosas aquí http://stackoverflow.com/questions/682367/good-python-modules-for-fuzzy-string-comparison –

Respuesta

10

Parece que Shawn Chin ha proporcionado la mejor solución, pero si no puede usar módulos no integrados, parece que get_close_matches desde difflib pueden ayudar:

import difflib 
difflib.get_close_matches("LUMB", ["JIBM", "NUNE", "NUMB"], 1) 

El número de diferencias puede ser obtenido usando el método de get_opcodesSequenceMatcher y trabajar con su valor de retorno.

+0

Si bien esto no devuelve la distancia de edición, me gusta que solo use la biblioteca estándar. +1 –

6

Usando pylevenshtein para calcular Levenshtein distance:

>>> from Levenshtein import distance 
>>> from operator import itemgetter 
>>> lst = ["JIBM", "NUNE", "NUMB"] 
>>> min([(x, distance("LUMB", x)) for x in lst], key=itemgetter(1)) 
('NUMB', 1) 

O, como una función:

from Levenshtein import distance 
from operator import itemgetter 
def closest(word, lst): 
    return min([(x, distance(word, x)) for x in lst], key=itemgetter(1)) 

print closest("NUMB", ["JIBM", "NUNE", "NUMB"]) 

P. S. Si desea evitar dependencias adicionales, siempre puede implementar su propia función para calcular la distancia. Por ejemplo, varias versiones se proponen en wikibooks cada una con sus propios pros y contras.

Sin embargo, si el rendimiento es una preocupación, considere adherirse a los módulos personalizados. Además de pylevenshtein, también hay python-levenshtein y nltk.metrics.distance (si ya usa NLTK).

Cuestiones relacionadas