¿Cómo eliminar subcadenas específicas de un conjunto de cadenas en Python?

160

Tengo un conjunto de cadenas set1, y todas las cadenas set1tienen dos subcadenas específicas que no necesito y quiero eliminar.
Entrada de muestra: set1={'Apple.good','Orange.good','Pear.bad','Pear.good','Banana.bad','Potato.bad'}
Entonces, básicamente, quiero eliminar las subcadenas .goody .badde todas las cadenas.
Lo que probé:

for x in set1:
    x.replace('.good','')
    x.replace('.bad','')

Pero esto no parece funcionar en absoluto. No hay absolutamente ningún cambio en la salida y es lo mismo que la entrada. Intenté usar en for x in list(set1)lugar del original, pero eso no cambia nada.

dominante
fuente

Respuestas:

187

Las cuerdas son inmutables. string.replace(python 2.x) o str.replace(python 3.x) crea una nueva cadena. Esto se afirma en la documentación:

Devuelve una copia de la cadena s con todas las apariciones de la subcadena antigua reemplazada por nueva. ...

Esto significa que debe reasignar el conjunto o volver a llenarlo (la reasignación es más fácil con la comprensión del conjunto) :

new_set = {x.replace('.good', '').replace('.bad', '') for x in set1}
Reut Sharabani
fuente
3
string.replace()está en desuso en python 3.x, ahora lo estástr.replace()
Yossarian42
71
>>> x = 'Pear.good'
>>> y = x.replace('.good','')
>>> y
'Pear'
>>> x
'Pear.good'

.replaceno cambia la cadena, devuelve una copia de la cadena con el reemplazo. No puede cambiar la cadena directamente porque las cadenas son inmutables.

Debe tomar los valores de retorno x.replacey colocarlos en un nuevo conjunto.

Alex Hall
fuente
Pero cuando hago un bucle sobre el conjunto de cadenas, ¿cómo puedo actualizar un nuevo conjunto? usando set_name.update? ¿Podrías mostrar eso?
controlfreak
12

¡Todo lo que necesitas es un poco de magia negra!

>>> a = ["cherry.bad","pear.good", "apple.good"]
>>> a = list(map(lambda x: x.replace('.good','').replace('.bad',''),a))
>>> a
['cherry', 'pear', 'apple']
gueeest
fuente
5

Podrías hacer esto:

import re
import string
set1={'Apple.good','Orange.good','Pear.bad','Pear.good','Banana.bad','Potato.bad'}

for x in set1:
    x.replace('.good',' ')
    x.replace('.bad',' ')
    x = re.sub('\.good$', '', x)
    x = re.sub('\.bad$', '', x)
    print(x)
Vivek
fuente
2
línea x.replace('.good',' ')y x.replace('.bad',' ')no hace nada al resultado final. La impresión será la misma sin ellos.
Srđan Popić
También preferiría tener una sola línea re.sub, como esta:x = re.sub('((\.good$)|(\.bad$))', '', x)
Srđan Popić
@ SrđanPopić, sí, estoy de acuerdo contigo
Vivek
¿deberíamos editarlo en consecuencia? (elimine replacesy mueva todo a una sola re.subllamada)
Srđan Popić el
1
@ SrđanPopić Publico esta respuesta porque es simple y paso a paso.
Vivek
3

Hice la prueba (pero no es su ejemplo) y los datos no los devuelven de manera ordenada o completa

>>> ind = ['p5','p1','p8','p4','p2','p8']
>>> newind = {x.replace('p','') for x in ind}
>>> newind
{'1', '2', '8', '5', '4'}

Probé que esto funciona:

>>> ind = ['p5','p1','p8','p4','p2','p8']
>>> newind = [x.replace('p','') for x in ind]
>>> newind
['5', '1', '8', '4', '2', '8']

o

>>> newind = []
>>> ind = ['p5','p1','p8','p4','p2','p8']
>>> for x in ind:
...     newind.append(x.replace('p',''))
>>> newind
['5', '1', '8', '4', '2', '8']
usuario140259
fuente
3

Cuando hay varias subcadenas para eliminar, una opción simple y efectiva es usar re.subun patrón compilado que implique unir todas las subcadenas para eliminar utilizando la |tubería regex OR ( ).

import re

to_remove = ['.good', '.bad']
strings = ['Apple.good','Orange.good','Pear.bad']

p = re.compile('|'.join(map(re.escape, to_remove))) # escape to handle metachars
[p.sub('', s) for s in strings]
# ['Apple', 'Orange', 'Pear']
cs95
fuente
1

Si la lista

Estaba haciendo algo para una lista que es un conjunto de cadenas y desea eliminar todas las líneas que tienen una cierta subcadena, puede hacer esto

import re
def RemoveInList(sub,LinSplitUnOr):
    indices = [i for i, x in enumerate(LinSplitUnOr) if re.search(sub, x)]
    A = [i for j, i in enumerate(LinSplitUnOr) if j not in indices]
    return A

donde subhay un patrón que no desea tener en una lista de líneasLinSplitUnOr

por ejemplo

A=['Apple.good','Orange.good','Pear.bad','Pear.good','Banana.bad','Potato.bad']
sub = 'good'
A=RemoveInList(sub,A)

Entonces Aserá

ingrese la descripción de la imagen aquí

rsc05
fuente
0

si elimina algo de la lista, puede usarlo de esta manera: (el método sub distingue entre mayúsculas y minúsculas)

new_list = []
old_list= ["ABCDEFG","HKLMNOP","QRSTUV"]

for data in old_list:
     new_list.append(re.sub("AB|M|TV", " ", data))

print(new_list) // output : [' CDEFG', 'HKL NOP', 'QRSTUV']
mamal
fuente