Me gustaría almacenar muchas palabras en una lista. Muchas de estas palabras son muy similares. Por ejemplo, tengo palabra afrykanerskojęzyczny
y muchos de palabras como afrykanerskojęzycznym
, afrykanerskojęzyczni
, nieafrykanerskojęzyczni
. ¿Cuál es la solución efectiva (rápida y con un tamaño de diferencia pequeño) para encontrar la diferencia entre dos cadenas y restaurar la segunda cadena de la primera y la diferencia?
python
string
python-3.x
diff
usuario2626682
fuente
fuente
difflib
? Si es así, consulte, por ejemplo, stackoverflow.com/questions/774316/…Respuestas:
Puede usar ndiff en el módulo difflib para hacer esto. Tiene toda la información necesaria para convertir una cadena en otra cadena.
Un simple ejemplo:
import difflib cases=[('afrykanerskojęzyczny', 'afrykanerskojęzycznym'), ('afrykanerskojęzyczni', 'nieafrykanerskojęzyczni'), ('afrykanerskojęzycznym', 'afrykanerskojęzyczny'), ('nieafrykanerskojęzyczni', 'afrykanerskojęzyczni'), ('nieafrynerskojęzyczni', 'afrykanerskojzyczni'), ('abcdefg','xac')] for a,b in cases: print('{} => {}'.format(a,b)) for i,s in enumerate(difflib.ndiff(a, b)): if s[0]==' ': continue elif s[0]=='-': print(u'Delete "{}" from position {}'.format(s[-1],i)) elif s[0]=='+': print(u'Add "{}" to position {}'.format(s[-1],i)) print()
huellas dactilares:
afrykanerskojęzyczny => afrykanerskojęzycznym Add "m" to position 20 afrykanerskojęzyczni => nieafrykanerskojęzyczni Add "n" to position 0 Add "i" to position 1 Add "e" to position 2 afrykanerskojęzycznym => afrykanerskojęzyczny Delete "m" from position 20 nieafrykanerskojęzyczni => afrykanerskojęzyczni Delete "n" from position 0 Delete "i" from position 1 Delete "e" from position 2 nieafrynerskojęzyczni => afrykanerskojzyczni Delete "n" from position 0 Delete "i" from position 1 Delete "e" from position 2 Add "k" to position 7 Add "a" to position 8 Delete "ę" from position 16 abcdefg => xac Add "x" to position 0 Delete "b" from position 2 Delete "d" from position 4 Delete "e" from position 5 Delete "f" from position 6 Delete "g" from position 7
fuente
ndiff
es un generador por lo que es bastante eficiente en memoria. Lo está invocando,list
lo que convierte las comparaciones de caracteres generadas individualmente en una lista completa de ellos. Solo tendría unos pocos en la memoria a la vez si no lo llamaralist
.Me gusta la respuesta ndiff, pero si desea escupirlo todo en una lista de solo los cambios, puede hacer algo como:
import difflib case_a = 'afrykbnerskojęzyczny' case_b = 'afrykanerskojęzycznym' output_list = [li for li in difflib.ndiff(case_a, case_b) if li[0] != ' ']
fuente
output_list = [li for li in list(difflib.ndiff(case_a,case_b)) if li[0] != ' ']
o 2) Cambie los nombres de las variables de cadena comocase_a -> a
ycase_b -> b
. ¡Salud!>>> output_list
:; # resultado #['- b', '+ a', '+ m']
if not li.startswith(' ')
es el equivalente deif li[0] != ' '
Algunos pueden encontrarlo más legible. O inclusoif item.startswith(('-', '+', ))
startswith()
partir de Python3.7.4
Puede mirar en el módulo regex (la sección difusa). No sé si puede obtener las diferencias reales, pero al menos puede especificar el número permitido de diferentes tipos de cambios como insertar, eliminar y sustituciones:
import regex sequence = 'afrykanerskojezyczny' queries = [ 'afrykanerskojezycznym', 'afrykanerskojezyczni', 'nieafrykanerskojezyczni' ] for q in queries: m = regex.search(r'(%s){e<=2}'%q, sequence) print 'match' if m else 'nomatch'
fuente
Lo que está pidiendo es una forma especializada de compresión. xdelta3 fue diseñado para este tipo particular de compresión, y hay un enlace de Python para él, pero probablemente podría salirse con la suya usando zlib directamente. Le gustaría usar
zlib.compressobj
yzlib.decompressobj
con elzdict
parámetro establecido en su "palabra base", por ejemploafrykanerskojęzyczny
.Las advertencias
zdict
solo se admiten en Python 3.3 y versiones posteriores, y es más fácil de codificar si tiene la misma "palabra base" para todas sus diferencias, que puede ser o no lo que desea.fuente
La respuesta a mi comentario anterior sobre la pregunta original me hace pensar que esto es todo lo que quiere:
loopnum = 0 word = 'afrykanerskojęzyczny' wordlist = ['afrykanerskojęzycznym','afrykanerskojęzyczni','nieafrykanerskojęzyczni'] for i in wordlist: wordlist[loopnum] = word loopnum += 1
Esto hará lo siguiente:
Para cada valor de la lista de palabras, establezca ese valor de la lista de palabras en el código original.
Todo lo que tiene que hacer es colocar este fragmento de código donde necesita cambiar la lista de palabras, asegurándose de almacenar las palabras que necesita cambiar en la lista de palabras y que la palabra original es correcta.
¡Espero que esto ayude!
fuente