2011-12-17 9 views
9

Tengo dos cadenas de igual longitud, ¿cómo puedo encontrar todas las ubicaciones donde las cadenas son diferentes?Encontrar la posición de la diferencia entre dos cadenas

Por ejemplo, "HELPMEPLZ" y "HELPNEPLX" son diferentes en las posiciones 4 y 8.

+0

me parece una tarea. muestre lo que intentó y dónde tiene problemas, luego intente hacer preguntas específicas – tback

+0

No es tarea, lo necesito para un complejo de funciones mucho más grande. Entonces, es un poco difícil escribir todo aquí ... –

+0

Pero las funciones dividen las cuerdas: ('HEL', 'PME', 'PLZ') y ('HEL', 'PNE', 'PLX') –

Respuesta

2

Si almacena las dos cadenas en a y b, puede recorrer todos los elementos y comprobar si hay desigualdad.

pitón intérprete interactivo:

>>> for i in range(len(a)): 
... if a[i] != b[i]: print i, a[i], b[i] 
... 
4 M N 
8 Z X 

Otra forma de hacerlo es con listas por comprensión. Todo está en una línea, y la salida es una lista.

>>> [i for i in range(len(a)) if a[i] != b[i]] 
[4, 8] 

Eso hace que sea muy fácil de envolver en una función, lo que hace que llamar a una variedad de entradas sea fácil.

>>> def dif(a, b): 
...  return [i for i in range(len(a)) if a[i] != b[i]] 
... 
>>> dif('HELPMEPLZ', 'HELPNEPLX') 
[4, 8] 
>>> dif('stackoverflow', 'stacklavaflow') 
[5, 6, 7, 8] 
+0

No utilice lambda cuando no sea necesario: 'def dif (a, b): return [i para i dentro del rango (len (a)) si a [i]! = B [i]]' –

+0

@StevenRumbalski, ¿por qué no? Hace exactamente lo mismo ... hasta donde yo sé. ¿Es solo menos pitonica? ¿O más lento? – FakeRainBrigand

+0

Las lambdas son para funciones * anónimas * y excelentes para crear líneas. Aquí, le asigna un nombre a la lambda, lo que sugiere que sería mejor como una función normal. Además, las lambdas oscurecen tu rastreo cuando tienes un error. –

1

La manera más fácil es dividir los datos en dos matrices CHAR y luego bucle a través de la comparación de las letras y devolver el índice cuando los dos caracteres no lo hacen iguales entre sí.

Este método funcionará bien siempre que ambas cadenas tengan la misma longitud.

1

Empareje las cadenas carácter por carácter e itere sobre esta colección junto con un índice de conteo. Prueba si los personajes en cada par difieren; si lo hacen, muestre el índice de dónde.

utilizar Python funciones incorporadas se puede hacer esto de forma ordenada en una línea:

>>> x = 'HELPMEPLZ' 
>>> y = 'HELPNEPLX' 
>>> {i for i, (left, right) in enumerate(zip(x,y)) if left != right} 
{8, 4} 
+0

Aunque OP no lo dijo, estaría dispuesto a apostar que sería preferible una solución que produjera los índices errantes en orden ascendente. –

+0

@Linus: si quieres esto, cambia los corchetes '{}' a '[]'. Eso le dará una lista de comprensión en lugar de una comprensión establecida, por lo que conserva el orden. – katrielalex

4
>>> from itertools import izip 
>>> s1 = 'HELPMEPLZ' 
>>> s2 = 'HELPNEPLX' 
>>> [i for i,(a1,a2) in enumerate(izip(s1,s2)) if a1!=a2] 
[4, 8] 
18

Prueba esto:

s1 = 'HELPMEPLZ' 
s2 = 'HELPNEPLX' 
[i for i in xrange(len(s1)) if s1[i] != s2[i]] 

volverá:

> [4, 8] 

Lo anterior la solución devolverá una lista w Con los índices en orden ordenado, no creará ninguna estructura de datos intermedia innecesaria y funcionará en Python 2.3 - 2.7. Para Python 3.x reemplace xrange por range.

+0

'zip' es un iterador en Python 3. No estoy seguro de lo que quiere decir con el comentario de Python 2.3. – katrielalex

+0

Significa que no utiliza funciones específicas de Python 3, como suponer que zip es un iterador, o que las comprensiones están disponibles. Mi solución funciona de manera eficiente incluso en las versiones anteriores de Python, siempre y cuando las comprensiones de la lista estén disponibles –

+0

Las comprensiones de conjuntos están en Python 2.7. – katrielalex

9

Python realmente viene con las baterías incluidas. Echar un vistazo a difflib

>>> import difflib 
>>> a='HELPMEPLZ' 
>>> b='HELPNEPLX' 
>>> s = difflib.SequenceMatcher(None, a, b) 
>>> for block in s.get_matching_blocks(): 
...  print block 
Match(a=0, b=0, size=4) 
Match(a=5, b=5, size=3) 
Match(a=9, b=9, size=0) 

difflib es muy potente y es muy recomendable un estudio parte de la documentación.

Cuestiones relacionadas