Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

357
Views
¿La mejor manera de Python para 'intercambiar' palabras (múltiples caracteres) en una cadena?

Considere los siguientes ejemplos:

 string_now = 'apple and avocado' stringthen = string_now.swap('apple', 'avocado') # stringthen = 'avocado and apple'

y:

 string_now = 'fffffeeeeeddffee' stringthen = string_now.swap('fffff', 'eeeee') # stringthen = 'eeeeefffffddffee'

Los enfoques discutidos en Cambiar carácter de cadena en Python no funcionan, ya que la técnica de mapeo utilizada allí solo tiene en cuenta un carácter. El str.maketrans() incorporado de Python también solo admite traducciones de un carácter, ya que cuando intento hacer varios caracteres, arroja el siguiente error:

ingrese la descripción de la imagen aquí

Una cadena de métodos replace() no solo está lejos de ser ideal (dado que tengo muchos reemplazos que hacer, encadenar reemplazos sería una gran parte del código), sino que debido a su naturaleza secuencial, no traducirá las cosas perfectamente como:

 string_now = 'apple and avocado' stringthen = string_now.replace('apple','avocado').replace('avocado','apple')

da 'apple and apple' en lugar de 'avocado and apple' .

¿Cuál es la mejor manera de lograr esto?

over 4 years ago · Santiago Trujillo
5 answers
Answer question

0

Me las arreglé para hacer esta función que hace exactamente lo que quieres.

 def swapwords(mystr, firstword, secondword): splitstr = mystr.split(" ") for i in range(len(splitstr)): if splitstr[i] == firstword: splitstr[i] = secondword i+=1 if splitstr[i] == secondword: splitstr[i] = firstword i+=1 newstr = " ".join(splitstr) return newstr

Básicamente, lo que esto hace es tomar su cadena "Apples and Avacados" por espacios. Por lo tanto, cada palabra se indexa en una matriz splitstr[] . Usando esto, podemos usar un ciclo for para intercambiar las palabras. El i+=1 es para asegurar que las palabras no se intercambien dos veces. Por último, vuelvo a unir la cadena usando newstr= " ".join(splitstr) que une las palabras separadas por un espacio.

Ejecutando el siguiente código nos da: Avacados and Apples .

over 4 years ago · Santiago Trujillo Report

0

Dado que queremos intercambiar palabras x e y , y que no nos importa la situación en la que se superponen, podemos:

  • dividir la cadena en las ocurrencias de x
  • dentro de cada pieza, reemplaza y con x
  • unir las piezas con y

Esencialmente, usamos puntos de división dentro de la cadena como un marcador temporal para evitar el problema con los reemplazos secuenciales.

Por lo tanto:

 def swap_words(s, x, y): return y.join(part.replace(y, x) for part in s.split(x))

Pruébalo:

 >>> swap_words('apples and avocados and avocados and apples', 'apples', 'avocados') 'avocados and apples and apples and avocados' >>>
over 4 years ago · Santiago Trujillo Report

0

Dos soluciones de expresiones regulares y una para otras personas que tienen un carácter que no puede aparecer (después de todo, hay más de un millón de caracteres posibles diferentes) y a quienes no les disgusta replace cadenas :-)

 def swap_words_regex1(s, x, y): return re.sub(re.escape(x) + '|' + re.escape(y), lambda m: (x if m[0] == y else y), s) def swap_words_regex2(s, x, y): return re.sub(f'({re.escape(x)})|{re.escape(y)}', lambda m: x if m[1] is None else y, s) def swap_words_replaces(s, x, y): return s.replace(x, chr(0)).replace(y, x).replace(chr(0), y)

Algunos resultados de referencia:

 3.7 ms 1966 kB swap_words_split 10.7 ms 2121 kB swap_words_regex1 17.8 ms 2121 kB swap_words_regex2 1.3 ms 890 kB swap_words_replaces

Código completo ( ¡Pruébelo en línea! ):

 from timeit import repeat import re import tracemalloc as tm def swap_words_split(s, x, y): return y.join(part.replace(y, x) for part in s.split(x)) def swap_words_regex1(s, x, y): return re.sub(re.escape(x) + '|' + re.escape(y), lambda m: (x if m[0] == y else y), s) def swap_words_regex2(s, x, y): return re.sub(f'({re.escape(x)})|{re.escape(y)}', lambda m: x if m[1] is None else y, s) def swap_words_replaces(s, x, y): return s.replace(x, chr(0)).replace(y, x).replace(chr(0), y) funcs = swap_words_split, swap_words_regex1, swap_words_regex2, swap_words_replaces args = 'apples and avocados and bananas and oranges and ' * 10000, 'apples', 'avocados' for _ in range(3): for func in funcs: t = min(repeat(lambda: func(*args), number=1)) tm.start() func(*args) memory = tm.get_traced_memory()[1] tm.stop() print(f'{t * 1e3:4.1f} ms {memory // 1000:4} kB {func.__name__}') print()
over 4 years ago · Santiago Trujillo Report

0

¿Por qué no usar una cadena temporal que nunca estará en la cadena de origen?

por ejemplo:

 >>> a = 'apples and avocados and avocados and apples' >>> b = a.replace('apples', '#IamYourFather#').replace('avocados', 'apples').replace('#IamYourFather#', 'avocados') >>> print(b) avocados and apples and apples and avocados

donde #IamYourFather# es una cadena que nunca estará en la cadena de origen.

over 4 years ago · Santiago Trujillo Report

0

Esta solución usa str.format() :

 string_now = "apple and avocado" stringthen = ( # "avocado and apple" string_now.replace("apple", "{apple}") .replace("avocado", "{avocado}") .format(apple="avocado", avocado="apple") ) # Edit: as a function def swap_words(s, x, y): return s.replace(x, "{" + x + "}") .replace(y, "{" + y + "}") .format(**{x: y, y: x})

Primero agrega corchetes antes y después de las palabras clave para convertirlas en marcadores de posición. Luego se str.format() para reemplazar los marcadores de posición.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!