Estoy escribiendo un código de Python para encontrar los caracteres comunes en 2 cadenas. El siguiente es el código:

class CharactersInString:
    def __init__(self, value1, value2):
        self.value1 = value1
        self.value2 = value2

    def find_chars_order_n(self):
        new_string = [ ]
        new_string1 = " "
        new_value1 = list(self.value1)
        new_value2 = list(self.value2)
        print( "new_value1: ", new_value1)
        print( "new_value2: ", new_value2)
        for i in new_value1:
            if i in new_value2:
                new_string.append(i)
        print(new_string)
        new_list = set(new_string)
        final_list = list(new_list)
        print(final_list)
        print(''.join(final_list))

if __name__ == "__main__":
     obj = CharactersInString("hello manzer", "helzo killmse")
     print(obj.find_chars_order_n())

La salida deseada es helo mz. El código anterior me da la salida como elzohm. Quiero obtener los caracteres únicos y también, el orden de los caracteres debe mantenerse según el valor 1. El uso de SET no proporciona un conjunto ordenado. Soy nuevo en python. ¿Podría ayudarme a obtener el resultado deseado y mantener el orden de la cadena?

2
user11549576 6 oct. 2019 a las 21:04

3 respuestas

La mejor respuesta

Puede agregar una condición para ver si la letra está allí dentro de la lista antes de agregarla.

Pruebe el siguiente código:

class CharactersInString:
    def __init__(self, value1, value2):
        self.value1 = value1
        self.value2 = value2

    def find_chars_order_n(self):
        new_string = []
        # new_value1 = list(self.value1)
        # new_value2 = list(self.value2)
        # print( "new_value1: ", new_value1)
        # print( "new_value2: ", new_value2)
        for i in self.value1:
            if i in self.value2 and i not in new_string:
                new_string.append(i)
        # print(new_string)
        # new_list = set(new_string)
        final_list = list(new_string)
        # print(final_list)
        return ''.join(final_list)

if __name__ == "__main__":
     obj = CharactersInString("hello manzer", "helzo killmse")
     print(obj.find_chars_order_n())

Salida:

helo mz

Como estamos iterando sobre el valor1, estamos seguros de que el orden estará de acuerdo con el valor1. Además, no estamos agregando un valor repetido al verificar con i not in new_string, por lo que debería ser mejor que "agregar" y luego eliminar usando un conjunto.

1
Amit Yadav 8 oct. 2019 a las 02:20

Dado que las teclas dict siguen su orden de inserción desde Python 3.7, puede usar las claves creadas a partir del método dict.fromkeys para crear efectivamente un conjunto ordenado de value1, para que luego pueda iterar sobre este conjunto ordenado para probar si cada carácter está en value2, que se puede convertir en un conjunto primero para O (1) complejidad de tiempo de búsqueda, lo que resulta en una complejidad de tiempo general de O (n) :

def CharactersInString(value1, value2):
    set2 = set(value2)
    return ''.join(c for c in dict.fromkeys(value1) if c in set2)

Para:

CharactersInString("hello manzer", "helzo killmse")

Devuelve: 'helo mze'

O si no le importa usar el método dunder set.__contains__ para probar la membresía:

def CharactersInString(value1, value2):
    return ''.join(filter(set(value2).__contains__, dict.fromkeys(value1)))

Tenga en cuenta que puede usar collections.OrderedDict en su lugar si dict si está usando una versión anterior de Python.

0
blhsing 6 oct. 2019 a las 18:46

Además, el orden de los caracteres debe mantenerse según el valor 1. El uso de SET no proporciona un conjunto ordenado.

Puede escribir un código mucho más simple simplemente reordenando el contenido del conjunto después:

def unique_in_order_of_first(first, second):
    unique = set(first).intersection(second)
    return ''.join(sorted(unique, key=first.index))
0
Karl Knechtel 6 oct. 2019 a las 18:31
58259971